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; }
关键修复说明
- 读取所有字节:用
ifile.get()替代>>操作符,确保读取文件中的每一个字节,包括空白字符。 - 规范十六进制输出:用
setw(2)和setfill('0')保证每个字节输出两位十六进制数,格式统一无歧义。 - 正确写入二进制:用
ofile2.put(c)直接写入单个字节,避免ostream_iterator的文本模式转换问题。 - 强制写入磁盘:写入完成后调用
ofile2.close(),确保缓冲区数据全部写入磁盘,解决大文件为空的问题。 - 处理前缀:读取时先跳过"0x"前缀,确保十六进制数值解析正确。
内容的提问来源于stack exchange,提问作者Shader
相关产品推荐
相关产品推荐

