为什么我的 ofstream 写入导致比预期更多的字节?

Why does my ofstream write result in more bytes than expected?

编辑 1:我已经确定了触发此问题的十六进制组合,但仍无法修复它。请参阅底部的编辑:

原文Post:我正在尝试将数据从传感器传递到二进制文件。我正在使用制造商的示例代码和 DLL 一次获取 4096 个字节,然后尝试将其写入文件。我的最终文件大小在 4100 到 4114 字节之间变化,额外的位随机分布在整个文件中。

来自传感器的数据以 4096 长无符号字符结束。当我将每个字符发送到 std::cout 时,值都是正确的(因此传感器和与之通信的 DLL 正在工作)。但是,将整个字符写入二进制文件(使用 ofstream::write)和一次写入一个字符(使用 ofstream::put)一样失败。在下面的代码中,我删除了文件创建等的错误检查。

unsigned int uiread = 4096;
unsigned char ccdbuf[4096];
ofstream ofile;

/* DLL call stuff removed since it's hardware-specific */

ofile.open("camdata.bin");

// ofile.write(reinterpret_cast<const char*>(ccdbuf), uiread); // 4100 - 4114

for (int ii = 0; ii < uiread; ii++)
{
    std::cout << (int)ccdbuf[ii] << "\n";

    ofile.put(ccdbuf[ii]);                  // 4100 - 4114
    // ofile.put(5);                        // 4096

}

ofile.close();

被注释掉的 'ofile.write' 行是传感器制造商提供给我的。末尾的注释突出显示生成的文件长度从 4100 到 4114 字节不等,额外的位散布在整个文件中。

for 循环中的 'std::cout' 行显示了正确的值。

如果我写“5”4096 次,则该文件正是我所期望的(4096 字节)。但是,一次写入一个 char 向量会导致二进制记录长度可变(长于 4096),额外位的位置是随机的。

我怀疑我的问题出在从 unsigned char 到 ofstream::write 预期类型(const char?)的转换上,但我不知道如何解决它。提前致谢。

编辑 1: 我已经确定最初触发此行为的双字节字符串始终以 0x0A 结尾,但第一个不正确写入的数据实际上是该对的第一个字节。因此,发送到 std:cout 的文本输出的十六进制等效值可能是 0x890A、0xC00A 或 0xC20A,但当输出中断时,该字节对始终写入 0x0A0D。

查看构成第一个字节的位似乎并没有揭示 0x0A 之前的位模式,而且并非以 0x0A 结尾的每个双字节对都会触发错误。由于 ofstream::put 在 for 循环内,所以我觉得第一个写入错误是值 0x0A 之前的循环似乎很奇怪。

正如问题的评论中所指出的,通过不显式地将写入文件作为二进制文件打开 Windows 偶尔会修改写入。修改 ofstream::open 命令以包含二进制标志已解决问题。

ofile.open("camdata.bin", ios_base::binary);

替换

ofile.open("camdata.bin");