【问题标题】:C++ Rookie needs help to correct ofstream binary write problemC++ Rookie 需要帮助来纠正 ofstream 二进制写入问题
【发布时间】:2020-02-02 09:42:51
【问题描述】:

我正在编写一个编写二进制文件的小型命令行程序。我使用ofstream write(作为二进制文件打开)来输出文件。问题是当我运行程序时,生成的文件与我提供给写入命令的数据不匹配。

我的问题是:

  • 我的代码有什么问题?
  • 我该如何调试这个?

感谢和问候...保罗

这里是详细信息。

将输出限制为 196 字节,输出如下所示:

如果我在输出中再添加 68 个字节,我会得到:

请注意文件在偏移量 0x00000010 处是如何损坏的,数据被覆盖并插入了随机数据。可以使用以下代码重新创建问题:

#include <iostream>
#include <fstream>
#include <vector>

#include "Windows.h"

class PcapNgFile
{
public:
    std::ofstream pcapng;
    PcapNgFile(std::wstring fileName);
    void pcapWrite();
    void closePcapng() { pcapng.close(); };
};

PcapNgFile::PcapNgFile(std::wstring fileName)
    : pcapng(fileName.c_str(), std::ios::binary | std::ios::out)
{
    if (pcapng.is_open())  std::wcout << "Output file: " << fileName << std::endl;
}

void PcapNgFile::pcapWrite()
{
    std::vector<uint8_t> dataOut1
    {
      0x0d, 0x0a, 0x0a, 0x0d, 0x70, 0x00, 0x00, 0x00, 0x4d, 0x3c, 0x2b, 0x1a, 0x01, 0x00, 0x00, 0x00,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x18, 0x00,
      'M', 'i', 'c', 'r','o', 's', 'o', 'f', 't', ' ',
      'W', 'i', 'n', 'd', 'o', 'w', 's', ' ', 'S', 'e', 'r', 'v', 'e', 'r',
      0x04, 0x00, 0x2b, 0x00,
      'M', 'i', 'c', 'r','o', 's', 'o', 'f', 't', ' ', 'I', 'n', 't', 'e', 'r', 'n', 'e', 't', ' ',
      'I', 'n', 'f', 'o', 'r', 'm', 'a', 't', 'i', 'o', 'n', ' ', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's',
      ' ', '8', '.', '5', 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
      0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
      0x02, 0x00, 0x05, 0x00, 'B', 'a', 'b', 'e','l', 0x00, 0x00, 0x00, 0x03, 0x00, 0x13, 0x00,
      'B', 'a', 'b', 'e', 'l', ' ', 'D', 'D', 'D', ' ', 'C', 'o', 'n', 'v', 'e', 'r', 't', 'e', 'r',
      0x00, 0x38, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x86, 0x03, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x62, 0x03, 0x00, 0x00, 0x62, 0x03, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x0b, 0xab, 0xe1,
      0x00, 0x00, 0x00, 0x0b, 0xab, 0xe1,
      0xba, 0xbe, 0x10, 0x00, 0x00, 0x80,
      0x00, 0x00, 0x00, 0x00,
      0x03, 0x00, 0x65, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x2c, 0x03, 0x00, 0x00
    };

    pcapng.write((char*)&(dataOut1[0]), dataOut1.size());

    return;
}

int wmain(int argc, wchar_t** argv)
{
    PcapNgFile* outFile = new PcapNgFile(L"c:\\traces\\bug.pcapng"); // output file

    outFile->pcapWrite();
    outFile->closePcapng();

    return (0);
}

我在 Windows 10 上使用 Visual Studio 2019 社区版。

【问题讨论】:

  • 在 Ubuntu 机器上运行您自己发布的代码效果很好
  • 感谢您检查 Raz。我得到了非常不可预测的结果。如果我逐渐注释掉越来越多的向量初始化值,我发现向量中有 202 个字节它可以正常工作。我需要在加载之前清除矢量吗?我需要做些什么来初始化输出流吗?
  • 我想说你不需要做你提到的任何事情。根据我对 C++、流等的熟悉,这段代码应该可以正常工作。我想知道这是否是一个设置问题。也许您正在覆盖现有文件,而这做得不好,或者类似的东西。您可以尝试使用std::ios::trunc 截断文件吗?
  • 试过std::ios::trunc,但仍然遇到问题。
  • 我已将代码复制到另一台安装了 Visual Studio 2019 的 Windows 10 机器上。代码在这台机器上编译并运行正常。如果我获取生成的可执行文件并在原始 Windows 10 机器上运行它,数据将再次损坏。看来我有一个运行时问题。我会尝试自己回答这个问题并在此处添加答案。

标签: c++ ofstream


【解决方案1】:

嗯,这很令人沮丧。我正在使用带有十六进制查看器插件的 Notepad++ 来检查一台机器上的输出和另一台机器上的 UltraEdit。问题是 Notepad++ 随机显示的内容不正确,而 UltrEdit 显示的是预期的输出。

所以为了避免所有疑问,这是 Notepad++ 的问题,而不是 ofstream 写入的问题。我猜这并不奇怪。

【讨论】:

    猜你喜欢
    • 2013-09-01
    • 2021-12-27
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    相关资源
    最近更新 更多