Question

I have made the previous problem simpler to get the answer and understand it completely.

The problem is that I want to write a C++ program that converts an ordinary text file into binary and then reads that binary file and converts it to a text file so that this text file equals to first text file. I have wrote this simple code for it.

int main()
{

      string name1 = "first", name2 = "sec", name3 = "third";
      int j = 0, k = 0;

      ifstream ifs(name1.c_str()); // Here I want to read from the ordinary text file (name1).
      ifs >> j; // Now j equals to 5 because name1 contains digit 5.
      ifs.close();

      ofstream ofs(name2.c_str(), ios::binary);
      ofs.write(as_bytes(j), sizeof(int)); // Here I want to write that j to name2 file in binary mode.                      
      ofs.close();

      ifstream ifs1(name2.c_str(), ios::binary); // Here I want to read from that binary file (name2).
      ifs.read(as_bytes(k), sizeof(int)); // Here I hope k becomes 5.

      ofstream ofs1(name3.c_str());
      ofs1 << k; // Here I want to write that k to name3 file in ordinary text mode.

      ifs1.close();
      ofs1.close();
      // Now I hope both name1 and name2 contain 5.

      keep_window_open();
      return 0;
}

Now what the ofs.write(as_bytes(j), sizeof(int)); or ifs.read(as_bytes(k), sizeof(int)); exactly means?

My question is why, in practice, the file name1 contains digit 5 and its size is 1 byte. The name2 contains some character/sign like [] and its size is 4 bytes and name3 contains digit 0 and its size is 1 byte?

I'll completely appreciate your responses.

Please don't extent the issue by giving extra info and only think around this problem. I want to just understand it. (My machine is Windows 7 32-bit. My compiler is MVS 2012. And if any more info is needed just tell me.)

Was it helpful?

Solution

write and read

write and read methods are used for i/o operations with binary files.

They has the following prototypes:

write(memory_block, size);
read(memory_block, size);

The write writes size bytes from memory_block to associated file.

The read reads size bytes from associated file and writes it to a memory_block

For example, in your case,

ofs.write(as_bytes(j), sizeof(int));

writes bytes of j number into a bynary file named name2.

You can see more about input and output with files here.

Why you havn't number five in name2 five

You write the bytes of j variable to name2 file in binary i/o mode. Any i/o operation is performed independently of any format considerations in this mode. It don't add carriage return after written data. This means that you can't read the name2 file and see the five number there.

Why you have a zero number in name3 file

The reason is because of typo :)

First look at the lines

   ifstream ifs(name1.c_str()); // Here I want to read from the ordinary text file (name1).
   ifs >> j; // Now j equals to 5 because name1 contains digit 5.
   ifs.close();

And then look at the lines

 ifstream ifs1(name2.c_str(), ios::binary); // Here I want to read from that binary file (name2).
 ifs.read(as_bytes(k), sizeof(int)); // Here I hope k becomes 5.

You are trying to read bytes from already closed file stream object. Any operation with such objects ends up with error. You can check it out in this way:

assert(!ifs.read(as_bytes(k), sizeof(int)));

It is possible because read returns a mutable reference to ifs and ifs is convertible to boolean value.

Because of all stuff above in this section, the value of variable k stay unchanged. You can't read from closed file, you can't change the k value. Because of this the old value of k is written to the name3 file.

Working example

#include <assert.h>
#include <fstream>
#include <string>

using namespace std;

typedef char byte;

template<typename T>
byte* as_bytes(T* ptr) {
    return reinterpret_cast<byte*>(ptr);
}

int main()
{

    string
        name1 = "first.txt",
        name2 = "second.bin",
        name3 = "third.txt";

    int j = 0, k = 0;

    // Here I want to read from the ordinary text file (name1).
    ifstream ifs(name1.c_str());
    ifs >> j;
    // Now j equals to 5 because name1 contains digit 5.
    assert(j == 5);
    ifs.close();

    ofstream ofs(name2.c_str(), ios::binary);
    // Here I want to write that j to name2 file in binary mode.
    ofs.write(as_bytes(&j), sizeof(int));                      
    ofs.close();

    // Here I want to read from that binary file (name2).
    ifstream ifs1(name2.c_str(), ios::binary);
    // Here I hope k becomes 5.
    ifs1.read(as_bytes(&k), sizeof(int));


    ofstream ofs1(name3.c_str());
    // Here I want to write that k to name3 file in ordinary text mode.
    ofs1 << k;

    ifs1.close();
    ofs1.close();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top