我正在从一个文本文件中读取信息,然后将其输出到bin文件。我得到了正确写的名称,但整数和双精度不能正常工作。忽略系统(“暂停”),它们是我可以检查我的输出。
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
struct SaleSlip{
char name[20];
int prodID;
double value;
};
void main(){
fstream slips, binslip;
SaleSlip sales[17];
binslip.open("SaleSlips.bin", ios::out | ios::binary | ios::trunc);
slips.open("SaleSlips.txt", ios::in);
if(slips.eof()){
cout << "Cannot open file - SaleSlips.txt"<< endl;
system("pause");
exit(2);
}
int i = 0;
while(!slips.eof()){
slips >> sales[i].name;
slips.ignore(80, ' ');
slips >> sales[i].prodID;
slips.ignore(80, ' ');
slips >> sales[i].value;
slips.ignore(80, '\n');
cout << sales[i].name;
cout << sales[i].prodID;
cout << sales[i].value << endl;
binslip.write((const char *)&sales[i].name, sizeof(sales[i].name));
binslip.write((const char *)&sales[i].prodID, sizeof(sales[i].prodID));
binslip.write((const char *)&sales[i].value, sizeof(sales[i].value));
i++;
}
slips.close();
binslip.close();
system("pause");
}
SaleSlips.txt每个项目的一行有一行,所以“Ryan 2 1400.52”是一行。 Ryan被正确解释,但是当我从二进制文件中读回来时它是不对的,当我在textpad中检查它时也不是。
答案 0 :(得分:2)
binslip.write
是UnformattedOutputFunction。有格式化和未格式化的输入/输出。使用未格式化的输出时,您将原始字节写入文件。关于字节实际代表什么没有解释。
当你写信给SalesSlips.bin时,你写了字符后跟数字(而不是你认为是数字)。当您尝试检查SalesSlips.bin时,计算机会读取文本字符,并期望文件的其余部分是文本,但事实并非如此。数字与字符的表示方式不同。即使您只是单独处理数字,积分和浮点值在二进制中的表示也不同。你现在可能有点吸收,但要点是你需要使用FormattedOutputFunction。这将执行您正确输出数据所需的内部转换。
想象一下,你有一个数字,比方说,50。如果没有描述50代表什么的单位,这个数字就毫无意义。 50秒? 50英尺? 50个州?您可以将binslip.write
视为只写50,当您稍后尝试读取该文件时,您看到的只有50,并且您不明白它应该代表什么,这就是为什么它看起来像乱码给你。
要修复代码,您需要将binslip.write
行替换为:
binslip << sales[i].name << sales[i].prodID << sales[i].value;
在这种情况下,operator<<
表现为FormattedOutputFunction
,因此当您编写SaleSlips.bin时,可以在文本编辑器中打开它并按预期查看Ryan 2 1400.52
。
答案 1 :(得分:1)
在BINARY模式下读写时,不应在任何文本编辑器中读取数据。它根本没有用处。如果您想在文本编辑器中阅读它,建议使用NORMAL模式。
无论如何,如果您不打算在文本编辑器中查看BINARY数据,可以使用以下行来读取和写入二进制文件:
while(!slips.eof())
{
slips >> sales[i].name;
slips.ignore(80, ' ');
slips >> sales[i].prodID;
slips.ignore(80, ' ');
slips >> sales[i].value;
slips.ignore(80, '\n');
cout << sales[i].name;
cout << sales[i].prodID;
cout << sales[i].value << endl;
//// WRITE THE STRUCTURE AT ONCE
binslip.write((const char *)&sales[i], sizeof(sales[i]));
i++;
}
binslip.flush();
binslip.close();
//// OPEN UP THE FILE IN READ MODE
binslip.open("SaleSlips.bin", ios::in | ios::binary );
SaleSlip sale;
//// READ UP THE COMPLETE STRUCTURE
binslip.read((char *)&sale, sizeof(sale));
//// PRINT IT.
cout<<sale.name;
cout<<sale.prodID;
cout<<sale.value;