incomplete buffer read

I want to fill a buffer by reading data from a file. However the buffer gets incompletely filled.

To check what goes wrong I first look at the remaining amount of data in the file (= 4106). It seems that there is more than enough to fill the buffer ( = 4000).

However when I look in the buffer only 153 (count) floats seem to have been read out. The file position has become -1, although it should have been 4000 and the eof has been set.

can someone explain what has gone wrong here?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 	float buffer[1000];

	long pos = mFile.tellg(); //position in the ifstream
	mFile.seekg(0, mFile.end); // set to end of stream
	long Pose = mFile.tellg(); //position at end of file
	long diff = Pose - pos;    //How much characters => 4106
	int SzB = sizeof(float) * 1000; //4000 characters

        mFile.seekg(pos, mFile.beg);
	pos = mFile.tellg();
	mFile.read((char*)buffer, SzB);
	pos = mFile.tellg();

	int count = mFile.gcount() / sizeof(float);

	if (mFile.bad() || mFile.eof()){
		bool bBad = mFile.bad();
		bool bEof = mFile.eof();
	}
The code seems to work for me - but that may not mean much, since I had to make several assumptions, such as how the file was created, how it was opened, what other activity there has been prior to this code etc. etc.
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <iomanip>
#include <fstream>

using namespace std;

const char * fname = "floats.bin";

void create_file()
{
    ofstream fout(fname, ios::binary);
    for (float i=0; i<1000; i++)
        fout.write( reinterpret_cast<char *>(&i), sizeof(i));
}

int main()
{
    create_file();
    
    ifstream mFile(fname, ios::binary);   
    
    float buffer[1000];

    long pos = mFile.tellg();         // position in the ifstream
    mFile.seekg(0, mFile.end);        // set to end of stream
    long Pose = mFile.tellg();        // position at end of file
    long diff = Pose - pos;           // How much characters
    cout << "diff: " << diff << endl;
    int SzB = sizeof(float) * 1000;   

    mFile.seekg(pos, mFile.beg);
    pos = mFile.tellg();
    mFile.read((char*)buffer, SzB);
    pos = mFile.tellg();

    int count = mFile.gcount() / sizeof(float);
    cout << "count: " << count << endl;
    if (mFile.bad() || mFile.eof()){
        bool bBad = mFile.bad();
        bool bEof = mFile.eof();
        cout << boolalpha << "bBad: " << bBad << endl; 
        cout << "bEof: " << bEof << endl; 
    }     
    
    for (int i=0; i<count; i++)
        cout << setw(4) << buffer[i];
       
    return 0;
}

output:
diff: 4000
count: 1000
   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  
... etc. ...
... etc. ...
 992 993 994 995 996 997 998 999
One other comment.
4106 characters is sufficient for 1026.5 floats (of length 4). That may have caused buffer overflow and corruption of other areas of memory with unpredictable (but bad) results.
Thank you for your reply.

You're right it has to do with how the file is opened.

ifstream mFile(fname, ios::binary);

I hadn't used ios::binary.

So you seem to be able to use file.read on a file which is not opened with ios::binary without it complaining, only you don't get proper data back. It seems to be skipping certain characters so you end at the end of the file prematurely.

ok, my problem is solved, thanks again.
As a default, files are opened in text mode. Certain characters, particularly the line endings '\n' and '\r' may be interpreted/translated during input/output which would account for the difference. in binary mode, no such translation takes place.
Topic archived. No new replies allowed.