Akshit Bansal
Akshit Bansal

Reputation: 127

C++ reading incorrectly from file

So, i ran this program and the answer i expected was 26 but got -52 instead. Please explain why the code is reading the character incorrectly.

char x = 26;
ofstream ofile("file.txt");
ofile << x;
ifstream ifile("file.txt");
char y;
ifile >> y;
cout << (int)y;

Upvotes: 2

Views: 360

Answers (3)

Alan Birtles
Alan Birtles

Reputation: 36488

When you write to an ofstream the data you've written isn't written directly to the file but held into an in memory buffer, the buffer will only be written to the file when the buffer is full, you seek the stream, flush the stream or close the stream.

Also note that if you aren't writing plain text it is safer to open the file in binary mode to ensure your exact data is read/written. You should also use read and write rather than the formatted i/o functions (or get and put for single characters).

It is also a good idea to add some error checking.

char x = 26;
ofstream ofile("file.txt", std::ios_base::binary);
ofile.put(x);
if (!ofile)
{
  std::cout << "write failed\n";
  return;
}
ofile.close();
ifstream ifile("file.txt", std::ios_base::binary);
char y;
ifile.get(y);
if (!ifile)
{
  std::cout << "read failed\n";
  return;
}
cout << (int)y << "\n";

Having tested on Windows the two required changes are

  1. Opening ifile in binary mode
  2. Closing/flushing ofile before opening iflie

Upvotes: 3

Forketyfork
Forketyfork

Reputation: 7810

If you want to write non-text data, you should open the file in binary mode:

ofstream ofile("file.txt", ios_base::binary);

A good practice is to check if the file was actually opened successfully:

ofstream ofile("file.txt", ios_base::binary);
if (!ofile) return -1;

Until you close the file, there's a high chance the buffer is not flushed, so there's no point in reading the file in another stream before you close it:

ofile << x;
ofile.close();

A good idea is to finish the output to cout with endl:

cout << (int) y << endl;

So you need something like:

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

int main() {
    char x = 26;

    ofstream ofile("file.txt", ios_base::binary);
    if (!ofile) return -1;
    ofile << x;
    ofile.close();

    ifstream ifile("file.txt", ios_base::binary);
    if (!ifile) return -1;
    char y;
    ifile >> y;
    cout << (int) y << endl;
    ifile.close();

    return 0;
}

Upvotes: 4

Manuel
Manuel

Reputation: 2554

This does what you want.

    char x = 26;
    ofstream ofile("file.txt");
    ofile << x;
    ofile.close ();       // <- closing the file
    ifstream ifile("file.txt");
    char y;
    ifile >> y;
    cout << "Value: " << (int)y << endl;
    return 0;

In this case it you may be reading something that's not yet written to disk (due to buffering.)

Output:

manuel@desktop:~/projects$ g++ -Wall -Wextra -g main.cc -o main -Wpedantic && ./main
Value: 26
manuel@desktop:~/projects$ hexdump file.txt 
0000000 001a                                   
0000001

Upvotes: 1

Related Questions