Re: [Dev-C++] Some extra bytes written to file?
Open Source C & C++ IDE for Windows
Brought to you by:
claplace
|
From: Per W. <pw...@ia...> - 2003-03-06 23:20:23
|
No problem about the extra 0x0d before a 0x0a.
Every heard about CR+LF, i.e. carriage return + line feed.
Whenever you open the file in text mode on a MSDos or Windows machine, you
will get the automatic addition, i.e. printf("hello\n"); will actually
emit "hello\r\n", and when you load the file in text mode, the extra CR
will be removed.
People normally only programming on Unix machines tries to forget this
little Microsoft extra, resulting in big problems reading and or writing
binary files.
/Per W
On Thu, 6 Mar 2003, "J=F6rgen" wrote:
> See comments...
>
> *********** REPLY SEPARATOR ***********
>
> On 2003-03-06 at 23:42 Ioannis Vranos wrote:
> Important correction:
>
>
> -------Original Message-------
>
> From: Ioannis Vranos
> Date: =D0=DD=EC=F0=F4=E7, 6 =CC=DC=F1=F4=E9=EF=F2 2003 11:37:40 =EC=EC
> To: Dev-C++ Mailing List
> Subject: Re: [Dev-C++] Some extra bytes written to file?
>
> -------Original Message-------
>
> From: "J=F6rgen"
> Date: =D0=DD=EC=F0=F4=E7, 6 =CC=DC=F1=F4=E9=EF=F2 2003 5:00:15 =EC=EC
> To: dev...@li...
> Subject: [Dev-C++] Some extra bytes written to file?
>
> Hi.
>
> This problem puzzles me. I have the following data.
> -4 0 0 4 1 0 4 2 0 3 2 27 1 3 108 1 3 135 1 3 189 1 3 351 1 4 0 8 5 0 4 6=
0
> 4 7 0 4 8 0 4 9
> 0 3 9 27 1 10 27 2 10 36 1 10 54 1 11 108 1 11 189 1
>
> I'm not to familiar with reg.exp, but I guess that the reg.exp. for the d=
ata
> would be
> result [value1 value2 value3]*
>
> where
> result is an integer but is always in the range -64 to 64
> value1 is an integer but is always in the range 0 to 11
> value2 is an integer but is always in the range 0 to 65536
> value3 is an integer but is always in the range 0 to 4
>
> let's say that we call [value1 value2 value3] for 'value' and 'nbrOfValue=
s'
> the number of sets
> of 'value'. In this case nbrOfvalues =3D 20
>
> When I write the data to file, using ofstream foo("foofile") I do it in t=
he
> following way
>
>
> =3D=3D> Since it is C++, why don't you use bitset<> elegantly and efficie=
ntly?
> [commment]
> Where should I use it? I can't see the purpose for it.
>
>
> if(result < 0)
> foo << '-';
> else
> foo << '+';
> foo << ((unsigned char) (abs(result) & 0x000000FF));
>
> for(int i=3D0; i<numberOfValues; i++){
> foo << ((unsigned char) (value[i][0] & 0x000000FF));
> foo << ((unsigned char) ((value[i][1] & 0x0000FF00) >> 8));
> foo << ((unsigned char) (value[i][1] & 0x000000FF));
> foo << ((unsigned char) (value[i][2] & 0x000000FF));
>
>
> =3D=3D> CORRECTION: Since value2 is [0,65536] use unsigned long. E.g.
>
> for(int i=3D0; i<numberOfValues; i++){
> foo << static_cast<unsigned long> (value[i][0]) & 0x000000FF;
> foo << static_cast<unsigned long>(value[i][1]) & 0x0000FF00 >> 8;
> foo << static_cast<unsigned long> (value[i][1]) & 0x000000FF;
> foo << static_cast<unsigned long> (value[i][2]) & 0x000000FF;
>
>
> =3D=3D>CORRECTION: The casting should be applied "before" the bitwise ope=
ration.
> [comment]
> What I'm trying to do is to reduce the size of the written file. Casting =
to unsigned long gives me no reduction in size.
> E.g.
> 4 * char =3D 4 * 8 =3D 32 bits =3D 4 bytes.
> 4 * unsigned long =3D 4 * 32 =3D 128 bits =3D 32 bytes
>
>
>
>
> }
>
> The problem comes when I read the data from file. If I just reverse the
> procedure and prints
> the decoded data to screen I get
> -4 0 0 4 1 0 4 2 0 3 2 27 1 3 108 1 3 135 1 3 189 1 3 351 1 4 0 8 5 0 4 6=
0
> 4 7 0 4 8 0 4 9 0
> 3 9 27 1 10 27 2 10 36 1 10 54 1 11 108 1 11 189 1 0 80 114
>
> It looks just the same as the original data except for the last three
> numbers (0 80 114).
>
> When looking at the filesize it shows that it is 85 bytes, but the data
> written is only 82 bytes
>
> For debugging purposes, instead of writing directly to file, I first stor=
e
> everything in a
> string s. That is, replacing foo << ... with s +=3D ... Finally I write i=
t to
> file with foo << s;
>
> When I print the string s to screen in hex-mode
>
> cout.setf( ios_base::hex, ios_base::basefield );
> for(int i=3D0; i<s.size(); i++)
> cout << " " << s[i];
>
> it gives the following output
> 2d 4 0 0 0 4 1 0 0 4 2 0 0 3 2 0 1b 1 3 0 6c 1 3 0 87 1 3 0 bd 1 3 1 5f 1=
4
> 0 0 8 5 0 0 4 6 0
> 0 4 7 0 0 4 8 0 0 4 9 0 0 3 9 0 1b 1 a 0 1b 2 a 0 24 1 a 0 36 1 b 0 6c 1 =
b
> 0 bd 1
> and it is the way it should be
>
> But when I look at the datafile in a hexeditor I see
> 2d 4 0 0 0 4 1 0 0 4 2 0 0 3 2 0 1b 1 3 0 6c 1 3 0 87 1 3 0 bd 1 3 1 5f 1=
4
> 0 0 8 5 0 0 4 6 0
> 0 4 7 0 0 4 8 0 0 4 9 0 0 3 9 0 1b 1 d a 0 1b 2 d a 0 24 1 d a 0 36 1 b 0=
6c
> 1 b 0 bd 1
>
> An extra byte 'd' emerges before every one of the three "value1"-'a' byte=
s
> (d a 0 1b 2 , d a 0 24 1 , d a 0 36 1).
>
> Where did these 'd' bytes come from?
>
>
> =3D=3D> Truncation. You "bitwise" a signed value (casted to unsigned type=
) and
> its bit, marking its signess floats around. Also keep in mind that the
> binary representation of negative values is radically different from the
> positive ones.
>
> [comment]
> First. There are no negative integers (int) in the data so the problem sh=
ouldn't be happening.
> Second. Lets say that the value of the int to be casted is 130. In bits i=
t is written
> 00000000 00000000 00000000 10000010
> Then it is masket with
> 00000000 00000000 00000000 11111111
> and the result is
> 00000000 00000000 00000000 10000010
> Now it is casted to unsigned char and we got the following bits
> 10000010
> The value is still 130. If it were a signed char the bitrepresentation wo=
uld still be
> 10000010
> but the value would be -126
>
>
>
> Why are the only occuring in front of the 'a' byte?
> How come that when I print the data to screen it does not mess up the val=
ues
> but instead
> appends (0 80 114) at the end?
>
>
> =3D=3D> Hmmm.
> [comment]
> Couldn't agree more
>
>
>
> Ioannis Vranos
>
> * Programming pages: http://www.noicys.freeurl.com
> * Alternative URL: http://run.to/noicys
>
>
|