s.r.a
s.r.a

Reputation: 33

Converting between text files and binary files in C++

For converting an ordinary text file into binary and then convert that binary file back to a text file so that the first text file equals with the last text file, I have wrote below code. But the bintex text file and the final text file aren't equal. I don't know which part of code is incorrect. Input sample ("bintex") contains this: 1983 1362 The result ("final") contains this: 959788084 which of course are not equal.

#include <iostream>
#include <fstream>
using namespace std;

int main() try
{
    string name1 = "bintex", name2 = "texbin", name3 = "final";

     ifstream ifs1(name1.c_str());
     if(!ifs1) error("Can't open file for reading.");

     vector<int>v1, v2;
     int i;
     while(ifs1.read(as_bytes(i), sizeof(int)));
     v1.push_back(i);
     ifs1.close();

     ofstream ofs1(name2.c_str(), ios::binary);
     if(!ofs1) error("Can't open file for writting.");
     for(int i=0; i<v1.size(); i++)
         ofs1 << v1[i];
         ofs1.close();

     ifstream ifs2(name2.c_str(), ios::binary);
      if(!ifs2) error("Can't open file for reading.");

         while(ifs2.read(as_bytes(i), sizeof(int)));
          v2.push_back(i);
          ifs2.close();

     ofstream ofs2(name3.c_str());
     if(!ofs2) error("Can't open file for writting.");
     for(int i=0; i<v2.size(); i++)
         ofs2 << v2[i];
         ofs2.close();

        keep_window_open();
        return 0;
}

//********************************

catch(exception& e) 
{
    cerr << e.what() << endl;
    keep_window_open();
    return 0;
}

Upvotes: 1

Views: 173

Answers (3)

James Kanze
James Kanze

Reputation: 153919

It's not clear (to me, at least), what you are trying to do. When you say that the orginal file contains 1983 1262, what do you really mean? That it contains two four byte integers, in some unspecified format, whose values are 1983 and 1262? If so, the problem is probably due to your machine not using the same format. You cannot, in general, just read bytes (using istream::read) and expect them to mean anything in your machine's internal format. You have to read the bytes into a buffer, and unformat them, according to the format with which they were written.

Of course, opening a stream in binary mode doesn't mean that the actual data are in some binary format; it just affects things like how (or more strictly speaking, whether) line endings are encoded, and how end of file is recognized. (Strictly speaking, a binary file is not divided into lines. It is just a sequence of bytes. Of course, some of those bytes might have values that you, in your program, interpret and new line characters.) If your file actually contains nine bytes with characters corresponding to "1983 1362", then you'll have to parse them as a text format, even if the file is written in binary. You can do this by reading the entire file into a string, and usingstd::istringstream; _or_, on most common systems (but not necessarily on all exotics) by using>>` to read, just as you would with a text file.

EDIT:

Just a simple reminder: you don't show the code for as_bytes, but I'm willing to guess that there's a reinterpret_cast in it. And any time you have to use a reinterpret cast, you can be very sure that what you're doing isn't portable, and if it's supposed to be portable, you're doing it wrong.

Upvotes: 0

RichardPlunkett
RichardPlunkett

Reputation: 2988

Your read and write operations aren't symmetric.

ifs1.read(as_bytes(i), sizeof(int))

grabs 4 bytes, and dumps the values into the char* its passed.

ofs1 << v1[i];

output the integer in v[i] as text. Those are very very different formats. If you used >> to read you would have a lot more success.

To expound, the first read might look like this {'1','9','8','3'}, which I would guess would be the 959788084 you are seeing when you pun it to an int. Your second read would be {' ','1','3','6'}, like not what you'd hoped for either.

Upvotes: 0

John Zwinck
John Zwinck

Reputation: 249153

What is this?

 while(ifs1.read(as_bytes(i), sizeof(int)));

It looks like a loop that reads all input and throws it away. The line afterward suggests that you should be using braces instead of a semicolon there, and doing the write in the block.

Upvotes: 1

Related Questions