fstream ignores reading numbers 9-13 from file

I have created a small test to try so you can see what the problem is. Why is it when using ints 9-13, also 32 (probably some others too) that fstream writes them to the file with no problem. However when reading, they are ignored? I am assuming they are interpreted as being something else. Is there a way around this? You will see that the 10 is ignored on reading the file. I am quite sure this is something rather simple to solve.
Thanks for any help!
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
#include <stdio.h>
#include <fstream>
#include <iostream>
typedef unsigned char uint8;
using namespace std;
class txrx
{
public:
	struct data {
		uint8 s;
		uint8 d;
		uint8 st;
		uint8 f;
	}dta;
};

class fion: public txrx
{
public:
	void a(void);};

txrx bin;
fion op;
	char any;
int main(void)
{op.a();
return 0;}
void fion::a(void)
{
	dta.s = 10;
	dta.d = 122;
	dta.st = 50;
	dta.f = 100;
	
	 fstream snd;
	 snd.open("outfile",ios::out);
	   snd << dta.s << "\n"
	              << dta.d << "\n"
	              << dta.st << "\n"
	              << dta.f << "\n";
	  snd.close();
	
	   cout << "\ndta: ";
	   cout << (int)dta.s  
	        << (int)dta.d  
			<< (int)dta.st  
			<< (int)dta.f << "\n";
			
	fstream rcv;
	rcv.open("outfile",ios::in);
	rcv  >> dta.s  //problem is somewhere round here!
	     >> dta.d  
	     >> dta.st 
	     >> dta.f;
	  	  rcv.close();

	cout << "\ncode: ";
		cout << (int)dta.s
		     << (int)dta.d
		     << (int)dta.st
		     << (int)dta.f << "\n";
  return;
}
Last edited on
It might help if you posted the output in your file.
The problem is that what you send/receive is characters. When you use operator >> with an fstream object it omits 'space' characters and 10 seems to be one of those.

One solution would be to use rcv.get() to get the data from the file (but then you'll have to use two rcv.get()s for each char as you'll also have to get the newline character '\n' following every char).

A more decent solution would be to change your data to ints, but don't worry we'll do it in a way that won't affect the size of your struct ;) Forget the typedef for uint8 and declare your data struct like this:

1
2
3
4
5
6
struct data {
     unsigned int s:8;
     unsigned int d:8;
     unsigned int st:8;
     unsigned int f:8;
}dta;

The ":8" we add after each int declaration tells the compiler to actually reserve 8 bits (i.e. 1 byte) for this particular element of the struct. When you do such things the total bit count of your structure must be divisible by 8 (i.e. the size must be a multiple of 1 byte). I'm not sure but I think the compiler adds some data by itself to make this happen if you don't do it yourself but that's not a problem here coz the size of data is 4*8=32 bits = 4 bytes which already is a multiple of 1 byte ^^

EDIT:
Um... I guess if you use the second solution you can't use operator >> for input at all... :/ In this case do the reading/writing in binary mode, like this:

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
#include <stdio.h>
#include <fstream>
#include <iostream>

using namespace std;

class txrx
{
    public:

    struct data
    {
        unsigned int s:8;
        unsigned int d:8;
        unsigned int st:8;
        unsigned int f:8;
    }dta;
};

class fion: public txrx
{
    public:

	void a(void);
};

txrx bin;
fion op;
char any;

int main(void)
{
    op.a();
    return 0;
}

void fion::a(void)
{
    dta.s = 10;
    dta.d = 122;
    dta.st = 50;
    dta.f = 100;

    fstream snd;
    snd.open("outfile.txt",ios::out|ios::binary);
    snd.write((char*)&dta,4); //write 4 bytes
    snd.close();

    cout << "\ndta: ";
    cout << dta.s <<"\n"
        << dta.d <<"\n"
        << dta.st <<"\n"
        << dta.f << "\n";

    fstream rcv;
    rcv.open("outfile.txt",ios::in|ios::binary);
    rcv.read((char*)&dta,4); //read 4 bytes
    rcv.close();

    cout << "\ncode: ";
    cout << dta.s <<"\n"
        << dta.d <<"\n"
        << dta.st <<"\n"
        << dta.f << "\n";

    return;
}

Come to think of it... You could just change to binary mode from the beginning, the change to ints and the bit-field thing isn't necessary but IMO it's better this way, plus you don't have to cast the data elements to ints before using cout on them to view their values.
Last edited on
Topic archived. No new replies allowed.