Writing 10

C

Colm

Hi

I'm having a wierd problem and I was wondering if anyone else had
encountered something similar...

I have a program which reads in a 5 digit number from a file in
decimal format, converts it to an unsigned int and writes it back out
to another file... It works fine in most cases, but for some reason
for the number 10 it doesn't.

It's Windows XP using Borland C++ and the code is something like...

char cp_decimal_num[5];
int i_bytes_read=read(i_in_file_id, cp_decimal_num, 5);
if (i_bytes_read != 5)
perror ("Error reading");

unsigned int ui_output_num = atoi(cp_decimal_num);

int i_bytes_written=write(i_out_file_id, &ui_output_num, 2);
if (i_bytes_written != 2)
perror ("Error writing");

Now in most cases it reads in the five digit number, (e.g. "00100"),
converts it to an unsigned int (100), and then writes 2 bytes to the
output file (64, 00).

This works for any number except... for some reason if I try it with
the number 10, it doesn't work as expected. It reads in "00010",
converts it to 10 (I've checked this in debug), but when writes it,
where I was expecting to see...
0A 00
....there is actually 3 bytes...
0D 0A 00

Yet the i_bytes_written variable still claims to have written only 2
bytes.

Can anyone tell me what's going on here? Where's that extra 0D coming
from?

Thanks
Colm
 
K

Karl Heinz Buchegger

Colm said:
char cp_decimal_num[5];

char cp_decimal_num[6];

***

You need room for the terminating '\0' character, which atoi
expects to be there.
cp_decimal_num[5] = '\0';


int i_bytes_read=read(i_in_file_id, cp_decimal_num, 5);
if (i_bytes_read != 5)
perror ("Error reading");

unsigned int ui_output_num = atoi(cp_decimal_num);
[snip]

0A 00
...there is actually 3 bytes...
0D 0A 00

Yet the i_bytes_written variable still claims to have written only 2
bytes.

Can anyone tell me what's going on here? Where's that extra 0D coming
from?

You need to open the output file in binary mode.
Your runtime system is replacing a value of 10 (which it thinks
is a carriage return character) with the sequence 13, 10
(line feed , carriage return). This translation happens
in 'text mode' and is supressed in 'binary mode'.
 
P

Phillip Mills

It's Windows XP [...]

There's your problem. :) Seriously, Windows thinks it's smarter than
you are and messes with your bytes.

Can anyone tell me what's going on here? Where's that extra 0D coming
from?

Open the file as "binary" and the problem should go away. In "text"
mode, the OS thinks the 10 is a linefeed delimiter and wants to turn it
into a CR/LF pair.
 
J

Jerry Coffin

Hi

I'm having a wierd problem and I was wondering if anyone else had
encountered something similar...

I have a program which reads in a 5 digit number from a file in
decimal format, converts it to an unsigned int and writes it back out
to another file... It works fine in most cases, but for some reason
for the number 10 it doesn't.

You've opened the file in translated (text) mode. 0x0A is the end-line
character, and in text mode on Windows, this is translated to a
carriage return/line feed pair.

Specify ios::binary when you open the file.
 
H

Howard

You need to open the output file in binary mode.
Your runtime system is replacing a value of 10 (which it thinks
is a carriage return character) with the sequence 13, 10
(line feed , carriage return). This translation happens
in 'text mode' and is supressed in 'binary mode'.

You got that backwards. :) Character #10 is linefeed, #13 is carriage
return.

-Howard
 
K

Karl Heinz Buchegger

Howard said:
You got that backwards. :) Character #10 is linefeed, #13 is carriage
return.

Oops.
It's been a long time since ....

Thanks for the correction.
 
P

puppet_sock

[email protected] (Colm) wrote in message news: said:
converts it to 10 (I've checked this in debug), but when writes it,
where I was expecting to see...
0A 00
...there is actually 3 bytes...
0D 0A 00

This is not a C++ issue, but a Windows issue. You need to turn
off the thing where a bare linefeed is automatically supplied
with a carriage return.
Socks
 
J

Jerry Coffin

Phillip Mills said:
It's Windows XP [...]

There's your problem. :) Seriously, Windows thinks it's smarter than
you are and messes with your bytes.

That's simply not true -- Windows does nothing of the sort.

The translation is done by the C runtime library, and it happens
because you've _asked_ it to, not because it "thinks it's smarter than
you are". I'd also note that Windows is hardly alone in defining text
mode such that translated mode really involves doing a translation.
 
O

Old Wolf

I'm having a wierd problem and I was wondering if anyone else had
encountered something similar...

int i_bytes_read=read(i_in_file_id, cp_decimal_num, 5);
int i_bytes_written=write(i_out_file_id, &ui_output_num, 2);

This works for any number except... for some reason if I try it with
the number 10, it doesn't work as expected. It reads in "00010",
converts it to 10 (I've checked this in debug), but when writes it,
where I was expecting to see...
0A 00
...there is actually 3 bytes...
0D 0A 00

read() and write() are non-standard functions; you should use
fopen() to open the file in binary mode, and then fread() and
fwrite() instead. If you do this then your problem will go away.
 
P

Phillip Mills

Phillip Mills said:
It's Windows XP [...]

There's your problem. :) Seriously, Windows thinks it's smarter than
you are and messes with your bytes.

That's simply not true -- Windows does nothing of the sort.

Actually it is *simply* true -- in other words, true for practical
purposes. It only becomes questionable when you complicate it with
unnecessary pedantry.
The translation is done by the C runtime library,

You're just specifying which part of the Windows system is being
annoying, not actually contradicting anything.
and it happens
because you've _asked_ it to,

No, it happens without being "asked" anything of the sort. It
__defaults__ to writing more bytes than it was told to and more bytes
than it does on other systems under the same conditions. If the OP had
been required to ask for that behavior, he would probably not have
joined the legions who have stumbled on it over the years.
not because it "thinks it's smarter than
you are". I'd also note that Windows is hardly alone in defining text
mode such that translated mode really involves doing a translation.

Right.... DOS, too.
 
J

Jerry Coffin

[ ... ]
Actually it is *simply* true -- in other words, true for practical
purposes. It only becomes questionable when you complicate it with
unnecessary pedantry.

No -- not true for practical, or any other, purposes. You might be
able to argue that it was true for practical purposes if it was
required that every possible implementation of C++ for Windows acted
the same way -- but that's not the case, and in fact there are C++
compilers available for Windows that do NOT do such a translation. As
such, it's an important distinction because if the OP used a different
compiler on Windows, he'd find different behavior. If he believe that
it was Windows itself that caused the behavior in the first place,
this would lead to still greater confusion.
You're just specifying which part of the Windows system is being
annoying, not actually contradicting anything.

Perhaps that's the case on your planet, but it certainly isn't true
here on planet earth.
No, it happens without being "asked" anything of the sort. It
__defaults__ to writing more bytes than it was told to and more bytes
than it does on other systems under the same conditions. If the OP had
been required to ask for that behavior, he would probably not have
joined the legions who have stumbled on it over the years.

Quite the contrary -- the C standard specifies that translated mode is
the default, yes. That means that when you don't specify ios::binary,
you're _asking_ it to do whatever translation is needed to conform to
the local "customs" for a text file.

The fact that you've asked for this behavior tacitly doesn't change
the fact that you have asked for it. If the OP intends to learn to
program in C++, he needs to learn what parameters mean what when
calling standard library functions. Trying to teach him nonsense and
then claiming that it's true for practical purposes is NOT doing him
any favor.
Right.... DOS, too.

This makes you sound narrow-minded and ignorant. In addition to the
DOS, OS/2, Windows family, MacOS, VMS, z/OS, etc. require translation
of text files. On MacOS the translation is different from on Windows,
but about equally trivial. On VMS, z/OS, and a whole host of older IBM
mainframe OSes, the translations involved are decidedly less trivial,
to put it mildly.
 
R

Richard Herring

In message said:
(e-mail address removed) (Colm) wrote in message


This is not a C++ issue, but a Windows issue. You need to turn
off the thing where a bare linefeed is automatically supplied
with a carriage return.

That *is* a C++ issue, performed by the C++ runtime library before the
data gets anywhere near Windows, and turned off by passing
std::ios_base::binary as part of the second argument to
basic_fstream::eek:pen(). See other postings in this thread.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top