strange behavior in binary i/o

hey,

i'm getting some confusing results while performing what should be simple binary i/o operations. i've done some binary reading before of different formats (like fortran output), so i might be overthinking this, but this seems surprising. here's a test code snippet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  fstream fout(name, ios::out | ios::binary );
  for( int i=0; i!=25; ++i )
    fout.write(reinterpret_cast<char*>(&i),sizeof(int));
  fout.flush();
  fout.close();
  
  fstream fin(name, ios::in | ios::binary );
  char buf[101];
  fin.get(buf,101);
  for( int i=0; i!=25; ++i )
  {
    int *n;
    n = reinterpret_cast<int*>(buf+4*i);
    cout << *n << endl;
  }

(obvious checks and debugging output removed for clarity)

what's surprising to me is that i read 0 through 9 just fine, but then i start to get large negatives, zeros, etc. i'm running gcc on macos x. i've tried many different approaches to the interpretation, including a few manufactured operators, and each has read to 8 or 9 and then given me junk. anyone have any thoughts on this?

thanks,
michael
Last edited on
When you read your numbers back, you use the get method which stops when it finds the first occurrence of the newline character in the file. On your system the newline character should have the value 10, so when get reaches the 11th value, it stops reading. As an outcome, only the first 10 values (0-9) are actually loaded in buf, followed by a '\0'. The other locations are left uninitialized (you can prove that by initializing the array to some meaningful values).

The simple fact that you are working in binary mode is unconsequential, because there is no difference between text mode and binary mode on systems where the newline sequence is a single char.

Simply switch to another method (i.e. istream::read) to avoid the I-stop-at-newline problem.

Bye
use istream::read () insted of get() method.
also have control on where you are writing and reading the bytes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

fstream fout(name,ios::out | ios::binary );
  for( int i=0; i!=25; ++i )
  {
	fout.write(reinterpret_cast<char*>(&i),sizeof(int));
	long pos=fout.tellp(); // tells the abs position of put pointer 
	cout << "pos=" << pos << endl; // to see it yourself
	fout.seekp(pos); // set next position to write
  }
    
  fout.flush();
  fout.close();
  
  fstream fin(name, ios::in | ios::binary );
  
  //char buf[101];
 // fin.get(buf,101);
  int pos=0;
  for(i=0; i!=25; ++i )
  {
    int n;
	fin.seekg(pos,ios::beg); // get pointer at the begining
	//read it 
	fin.read(reinterpret_cast<char*>(&n),sizeof(int));
    //n = reinterpret_cast<int*>(buf+4*i);
    cout << n << endl;
	pos=pos+sizeof(int);
  }
stream& get( char* pch, int nCount, char delim = '\n' );
Remember this is the signature of get. It's reading upto the \n in the file, which is 10. So your output is correct upto 9 and then junk as that's what was in buf.

http://msdn.microsoft.com/en-us/library/aa277360(VS.60).aspx
wow, thanks everyone! as usual, what was happening is simple and predictable when you know how things work : ) that cleared everything up.

cheers,
michael
Topic archived. No new replies allowed.