Trouble in ifstream reading structures

Hi everyone!

I have the code below which works fairly awesomely until I try and save an array of the 'test' structure. What happens is the code outputs this silly stuff. Any suggestions?


$ ./a
Testing 1 1
Testing 2 2
Testing 2 2
(null) 16297
▒▒▒ 4199552



(sub question) Why does do I get the extra 'Testing 2 2' line?

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// bin test

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>

void readIn();
void writeOut();

struct test {
	char* s;
	int n;
};


int main( int argsc, char* argsv[] )
{
	writeOut();
	readIn();
	return 0;
}

// write out the binary data
void writeOut()
{
	test t;
	t.s = "Testing 1";
	t.n = 1;

	test t2;
	t2.s = "Testing 2";
	t2.n = 2;

	std::ofstream of;
	of.open("data.bin", std::ios::out | std::ios::binary);
	of.write( (char*)&t, sizeof(test) );
	of.write( (char*)&t2,sizeof(test) );
	of.close();

	return;
}

void readIn()
{
	test t;

	std::ifstream ifs;
	ifs.open("data.bin", std::ios::in | std::ios::binary);
	
/*
	while( !ifs.eof() )
	{
		ifs.read( (char*)&t, sizeof(test) );
		printf("%s %d\n",t.s,t.n);
		if(ifs.eof()) break;
	}
*/
	int items=0;
	while( !ifs.eof() )
	{
		ifs.read( (char*)&t, sizeof(test) );
		printf("%s %d\n",t.s,t.n);
		items++;
	}
	items--;

	test things[items];
	ifs.seekg(0, std::ios_base::beg );
	int i;
	for( i=0; i<items; i++ )
	{
		ifs.read( (char*)&things[i], sizeof(test) );
	}

	for( i=0; i<items; i++ )
	{
		printf("%s %d\n",things[i].s,things[i].n);
	}
		
	ifs.close();

	return;
}


Thanks for the help!
-- bench
Don't loop of eof(). That only becomes true once you have already tried and failed to read from the file. Loop on good() instead.
Hi and thanks,

I tried your suggestion and changed while( !ifs.eof() ) to while( ifs.good() ) but now have this output:


$ ./a
Testing 1 1
Testing 2 2
Testing 2 2
 1628857248
%s %d
 2673532
(null) 1629767286


Hi benchsketch,
What is the function of -----------------ifs.read( (char*)&t, sizeof(test) );------------------
in your program?

Thanks.
Writing data out in binary like that is non-portable and doesn't work for pointers. You are saving the pointer, but not the data that it is pointing to.
Hey,

@swetzer I just wanted to count the number of structures in the file and that was a convenient way to do so.

@Galik thanks, I'll keep that in mind

Any suggestions on how to save a structure to a binary file?

Thanks,
bench
Hey! I figured out how to make it work! Yay:

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
      
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <fstream>

void writeOut();
void readIn();

struct test {
	short int n;
	char* s;
};

int main( int argsc, char* argsv[] )
{
	writeOut();
	readIn();
	return 0;
}

void writeOut()
{
	test t;
	std::ofstream of;
	of.open("data.bin", std::ios::out | std::ios::binary );
	
	t.s = "One";
	t.n = 1;
	of.write((char*)&t, sizeof(test) );
	t.s = "Two";
	t.n = 2;
	of.write((char*)&t, sizeof(test) );	
	of.close();
	return;
}

void readIn()
{
	printf("Reading in\n");
	
	test t;
	int items = 0;
	std::ifstream fs;
	fs.open("data.bin",std::ios::in | std::ios::binary);
	while( fs.good() )
	{
		fs.read((char*)&t,sizeof(test));
		// printf("%s %d\n",t.s,t.n);
		items++;
	}
	items--;

	//fs.seekg( 0 );
	fs.close();
	fs.open("data.bin", std::ios::binary);

	int i;
	test things[items];
	fs.read((char*)&things,sizeof(things));

	for( i=0; i<items; i++)
	{
		printf("%s %d\n",things[i].s,things[i].n);
	}

	return;
}


Gives this output


Reading in
One 1
Two 2



Somebody mentioned that this isn't portable though? Can somebody explain that?
Topic archived. No new replies allowed.