Writing 10

Discussion in 'C++' started by Colm, Sep 13, 2004.

  1. Colm

    Colm Guest

    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
     
    Colm, Sep 13, 2004
    #1
    1. Advertising

  2. Colm wrote:
    >
    >
    > 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'.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Sep 13, 2004
    #2
    1. Advertising

  3. In article <>,
    (Colm) wrote:

    > 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.

    --
    Phillip Mills
    Multi-platform software development
    (416) 224-0714
     
    Phillip Mills, Sep 13, 2004
    #3
  4. Colm

    Jerry Coffin Guest

    (Colm) wrote in message news:<>...
    > 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.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Sep 13, 2004
    #4
  5. Colm

    Howard Guest

    >
    > > 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'.
    >


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

    -Howard
     
    Howard, Sep 13, 2004
    #5
  6. Howard wrote:
    >
    > >
    > > > 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'.
    > >

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


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

    Thanks for the correction.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Sep 13, 2004
    #6
  7. Colm

    Guest

    (Colm) wrote in message news:<>...
    [snip]
    > 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
     
    , Sep 13, 2004
    #7
  8. Colm

    Jerry Coffin Guest

    Phillip Mills <> wrote in message news:<41458377$1_2@127.0.0.1>...
    > In article <>,
    > (Colm) wrote:
    >
    > > 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.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Sep 13, 2004
    #8
  9. Colm

    Old Wolf Guest

    (Colm) wrote:
    >
    > 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.
     
    Old Wolf, Sep 13, 2004
    #9
  10. In article <>,
    (Jerry Coffin) wrote:

    > Phillip Mills <> wrote in message
    > news:<41458377$1_2@127.0.0.1>...
    > > In article <>,
    > > (Colm) wrote:
    > >
    > > > 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.

    --
    Phillip Mills
    Multi-platform software development
    (416) 224-0714
     
    Phillip Mills, Sep 13, 2004
    #10
  11. Colm

    Jerry Coffin Guest

    Phillip Mills <> wrote in message news:<41461d82_2@127.0.0.1>...

    [ ... ]

    > > 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.


    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.

    > > 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.


    Perhaps that's the case on your planet, but it certainly isn't true
    here on planet earth.

    > > 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.


    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.

    > > 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.


    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.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Sep 14, 2004
    #11
  12. In message <>,
    writes
    > (Colm) wrote in message
    >news:<>...
    >[snip]
    >> 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.


    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.

    --
    Richard Herring
     
    Richard Herring, Sep 14, 2004
    #12
  13. Colm

    Colm Guest

    Thanks for your help lads I'll try that...
     
    Colm, Sep 16, 2004
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mark Kamoski
    Replies:
    1
    Views:
    2,465
  2. Amit
    Replies:
    8
    Views:
    3,866
    Alan Pretre
    Aug 4, 2003
  3. Kelly G.

    Writing XML file

    Kelly G., Jan 7, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    2,849
    Kelly G.
    Jan 8, 2004
  4. Terry Mulvany

    Writing applet-like apps...

    Terry Mulvany, Mar 2, 2004, in forum: ASP .Net
    Replies:
    4
    Views:
    773
    Itai Raz
    Mar 5, 2004
  5. HNguyen
    Replies:
    4
    Views:
    2,437
    HNguyen
    Dec 21, 2004
Loading...

Share This Page