1

我正在从一个文本文件中读取信息,然后将其输出到 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 中检查它时也不正确。

4

2 回答 2

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<<表现为 a FormattedOutputFunction,因此当您编写 SaleSlips.bin 时,您可以在文本编辑器中打开它并按照Ryan 2 1400.52您的预期进行查看。

于 2013-07-26T04:22:08.773 回答
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;
于 2013-07-26T05:10:50.490 回答