简体   繁体   中英

Visual C++ - Writing doubles and integers to binary files

I'm reading info from one text file, then outputting it to a bin file. I got the name to write properly, but the integer and doubles do not work properly. Disregard the system("pause"), they are so I can check my outputs.

#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 has one line per item of the array so "Ryan 2 1400.52" is one line. Ryan is interpreted correctly, but when I read back in from the binary it isn't right, nor is it when I check it in textpad.

binslip.write is an UnformattedOutputFunction . There is formatted and unformatted input/output. When you use unformatted output, you are writing raw bytes to the file. There is no interpretation as to what the bytes actually represent.

When you wrote to SalesSlips.bin, you wrote characters followed by numbers (rather, what you thought would be numbers). When you tried to examine SalesSlips.bin, the computer read text characters, and was expecting the rest of the file to be text, but it wasn't. Numbers are represented differently then characters. Even if you were to just deal with numbers alone, integral and floating point values are represented differently in binary. It may be a bit much for you to absorb right now, but the gist of it is you need to use a FormattedOutputFunction . This will perform the internal conversions necessary for you to output your data properly.

Imagine you have a number, lets say, 50. That number is meaningless without units that describe what 50 represents. 50 seconds? 50 feet? 50 states? You can think of binslip.write as just writing 50, and when you try to read the file later, all you see is 50, and you don't understand what it was supposed to represent, which is why it looks like gibberish to you.

To fix your code you need to replace the binslip.write lines with this:

binslip << sales[i].name << sales[i].prodID << sales[i].value;

In this case, operator<< behaves as a FormattedOutputFunction , so when you write SaleSlips.bin, you can open it in a text editor and view Ryan 2 1400.52 like you expected.

While reading and writing in BINARY mode, you are not expected to read the data in any text editor. It simply serves no purpose. If you want to read it in a text editor, recommendation is to use NORMAL mode.

Anyways, if you don't bother about viewing your BINARY data in a text editor, you could use the following lines to Read and write binary file:

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM