即使 ios::binary 也无法以二进制模式写入文件
Unable to write file in binary mode even with ios::binary
我按照 cplusplus.com 上的教程进行了 std::ofstream::binary,但似乎无法在二进制模式下获得我需要的十六进制输出。
我目前需要做一个密码学项目,要求输出为二进制模式(而不是将十六进制值写入文件内容)。
以下是我的代码摘录(带注释):
ofstream writeout(filename2.c_str(), ios::binary);
//ctextvec is the vector that stores the ciphertext
for (int i=0; i<ctextvec.size(); i+=2)
{
ostringstream oss, oss2;
//formatting of hex to string (adding missing '0')
oss << hex << setw(16) << setfill('0') << ctextvec[i];
oss2 << hex << setw(16) << setfill('0') << ctextvec[i+1];
//Stores all ciphertext characters as a string
storestr.append(oss.str());
storestr.append(oss2.str());
}
//Define new array to store characters for writing
char writearr[storestr.size()];
for(int i=0; i<storestr.size(); i++) writearr[i]=storestr[i];
//Perform write to file
for(int i=0; i<storestr.size(); i++)
writeout.write((char*)&writearr[i],sizeof(char));
writeout.flush();
writeout.close();
我尝试了很多方法,似乎都是将内容转储到文件中,而不是写入二进制模式。我应该需要此命令来显示文件已加密(至少)。
以下是我得到的文件的屏幕截图以及我应该得到的内容。
我得到的是:
我应该得到什么:
非常感谢任何帮助!
问题不在于您如何编写输出,而在于您向输出写入的内容。当您使用 ostringstream 时,您正在从 C6
转换为 63 36
或 'C6' 的 ASCII 表示。假设 ctextvec
是一个字符向量,您可以使用
for (int i=0;i>ctextvec.size();i++) {
writeout.write(ctextvec[i],sizeof(char));
}
或者如 tkausi 所说,您可以使用
writeout.write((char*)ctextvec.data(),sizeof(char)*ctextvec.size());
你的大部分代码都是不必要的,for-lop 甚至适得其反。
oss << hex << setw(16) << setfill('0') << ctextvec[i];
这会将二进制数 ctextvec[i]
转换为 ASCII 十六进制表示形式。这就是您最终在文件中得到的结果。
char writearr[storestr.size()];
for(int i=0; i<storestr.size(); i++) writearr[i]=storestr[i];
您从 std::string
复制 可以使用 c_str()
为您提供后备字符数组到另一个字符数组,为什么?
for(int i=0; i<storestr.size(); i++)
writeout.write((char*)&writearr[i],sizeof(char));
你一次写一个字节,为什么不直接推整个数组来写?
您只需:
ofstream writeout(filename2.c_str(), ios::binary);
writeout.write(reinterpret_cast<char*>(ctextvec.data()), ctextvec.size() * sizeof(ctextvec[0]));
writeout.close();
这应该完全符合您的要求。
我按照 cplusplus.com 上的教程进行了 std::ofstream::binary,但似乎无法在二进制模式下获得我需要的十六进制输出。
我目前需要做一个密码学项目,要求输出为二进制模式(而不是将十六进制值写入文件内容)。
以下是我的代码摘录(带注释):
ofstream writeout(filename2.c_str(), ios::binary);
//ctextvec is the vector that stores the ciphertext
for (int i=0; i<ctextvec.size(); i+=2)
{
ostringstream oss, oss2;
//formatting of hex to string (adding missing '0')
oss << hex << setw(16) << setfill('0') << ctextvec[i];
oss2 << hex << setw(16) << setfill('0') << ctextvec[i+1];
//Stores all ciphertext characters as a string
storestr.append(oss.str());
storestr.append(oss2.str());
}
//Define new array to store characters for writing
char writearr[storestr.size()];
for(int i=0; i<storestr.size(); i++) writearr[i]=storestr[i];
//Perform write to file
for(int i=0; i<storestr.size(); i++)
writeout.write((char*)&writearr[i],sizeof(char));
writeout.flush();
writeout.close();
我尝试了很多方法,似乎都是将内容转储到文件中,而不是写入二进制模式。我应该需要此命令来显示文件已加密(至少)。
以下是我得到的文件的屏幕截图以及我应该得到的内容。
我得到的是:
我应该得到什么:
非常感谢任何帮助!
问题不在于您如何编写输出,而在于您向输出写入的内容。当您使用 ostringstream 时,您正在从 C6
转换为 63 36
或 'C6' 的 ASCII 表示。假设 ctextvec
是一个字符向量,您可以使用
for (int i=0;i>ctextvec.size();i++) {
writeout.write(ctextvec[i],sizeof(char));
}
或者如 tkausi 所说,您可以使用
writeout.write((char*)ctextvec.data(),sizeof(char)*ctextvec.size());
你的大部分代码都是不必要的,for-lop 甚至适得其反。
oss << hex << setw(16) << setfill('0') << ctextvec[i];
这会将二进制数 ctextvec[i]
转换为 ASCII 十六进制表示形式。这就是您最终在文件中得到的结果。
char writearr[storestr.size()];
for(int i=0; i<storestr.size(); i++) writearr[i]=storestr[i];
您从 std::string
复制 可以使用 c_str()
为您提供后备字符数组到另一个字符数组,为什么?
for(int i=0; i<storestr.size(); i++)
writeout.write((char*)&writearr[i],sizeof(char));
你一次写一个字节,为什么不直接推整个数组来写?
您只需:
ofstream writeout(filename2.c_str(), ios::binary);
writeout.write(reinterpret_cast<char*>(ctextvec.data()), ctextvec.size() * sizeof(ctextvec[0]));
writeout.close();
这应该完全符合您的要求。