You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++存储文件十六进制表示后还原文件时出现异常的问题求助

问题分析与修复方案

核心问题点

  • 原文件读取丢失字节:用ifile >> byte读取二进制文件时,会自动跳过空白字符(空格、换行、制表符等),导致原文件中的空白字节被遗漏,后续还原的文件自然损坏。
  • 副本文件未写入磁盘:写入副本后未关闭ofile2或刷新缓冲区,大文件时数据仍停留在内存缓冲区,未写入磁盘,表现为空文件。
  • 二进制写入模式错误:ostream_iterator默认以文本模式处理输出,会对换行符等字节进行转换,破坏二进制文件结构。
  • 十六进制输出格式不规范:单个字节的十六进制可能只输出一位(如0x5而非0x05),虽不影响读取,但容易引发格式混淆。

修复后的代码

#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>
#include <windows.h>

using namespace std;

int main()
{
    ifstream ifile;
    ofstream ofile;
    ofstream ofile2;
    ifstream ifile2;
    string filename;
    unsigned char byte;
    unsigned int hexnum = 0;
    vector<unsigned char> charvec;

    cout << "input file name" << endl << endl;
    cin >> filename;

    // 读取原文件并生成规范十六进制文本
    ifile.open(filename, ios::binary);
    ofile.open("OUT" + filename + ".txt");

    if (ifile)
    {
        ofile << hex << setfill('0');
        // get方法读取所有字节,包括空白字符
        while (ifile.get(reinterpret_cast<char&>(byte)))
        {
            // 固定输出两位十六进制数
            ofile << "0x" << setw(2) << static_cast<int>(byte) << ' ';
        }
    }
    else
    {
        cout << "file not open";
    }

    ifile.close();
    ofile.close();

    // 读取十六进制文本并还原字节
    ifile2.open("OUT" + filename + ".txt");
    ofile2.open("OUT" + filename, ios::binary | ios::out);

    if (ifile2)
    {
        string prefix;
        // 先读取"0x"前缀,再读取十六进制数值
        while (ifile2 >> prefix >> hex >> hexnum)
        {
            charvec.push_back(static_cast<unsigned char>(hexnum));
        }
    }
    else
    {
        cout << "file not open";
    }
   
    // 直接写入二进制字节,避免文本模式转换问题
    for (unsigned char c : charvec)
    {
        ofile2.put(c);
    }

    // 关闭文件强制刷新缓冲区,确保数据写入磁盘
    ofile2.close();
    ifile2.close();
   
    Sleep(10000);
    return 0;
}

关键修复说明

  1. 读取所有字节:用ifile.get()替代>>操作符,确保读取文件中的每一个字节,包括空白字符。
  2. 规范十六进制输出:用setw(2)和setfill('0')保证每个字节输出两位十六进制数,格式统一无歧义。
  3. 正确写入二进制:用ofile2.put(c)直接写入单个字节,避免ostream_iterator的文本模式转换问题。
  4. 强制写入磁盘:写入完成后调用ofile2.close(),确保缓冲区数据全部写入磁盘,解决大文件为空的问题。
  5. 处理前缀:读取时先跳过"0x"前缀,确保十六进制数值解析正确。

内容的提问来源于stack exchange,提问作者Shader

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 23:10:16