fread() fails if specific byte at offset X

Discussion in 'C' started by bughunter2, Mar 2, 2007.

  1. bughunter2

    bughunter2 New Member

    Joined:
    Feb 27, 2007
    Messages:
    31
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Netherlands
    Home Page:
    http://reversemasters.nl/
    I think I discovered a bug but I'm not sure.

    fread() failed when I use fseek() to set the file pointer to some offset

    at the offset I set it to, the byte "0x1A" (in hexadecimal) could be found

    Funny thing is, when I use a hex editor and set the byte at that offset to 0x00 or something else than 0x1A, fread() succeeds :eek:

    If anyone does not completely understand me, feel free to ask.

    Please help.
     
  2. bughunter2

    bughunter2 New Member

    Joined:
    Feb 27, 2007
    Messages:
    31
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Netherlands
    Home Page:
    http://reversemasters.nl/
    I think I might have found it out by myself.

    Thinking about the EOF byte in Windows, (EOF = End Of File)
    Windows sees the byte 0x1A as the EOF of a text file, so I might have to open the file in binary mode.
     
  3. bughunter2

    bughunter2 New Member

    Joined:
    Feb 27, 2007
    Messages:
    31
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Netherlands
    Home Page:
    http://reversemasters.nl/
    Opening the file in binary mode fixed it, however this wouldn't be needed on a UNIX system.
     
  4. DaWei

    DaWei New Member

    Joined:
    Dec 6, 2006
    Messages:
    835
    Likes Received:
    5
    Trophy Points:
    0
    Occupation:
    Semi-retired EE
    Location:
    Texan now in Central NY
    Home Page:
    http://www.daweidesigns.com
    You are absolutely correct. Even in the situations where the soft EOF doesn't mess you up, there are other factors. In text mode, which is the Windows default, but doesn't even exist in *nix systems, a CR is added prior to every LF (newline) during a write. These are stripped out on the read, resulting in one getting the same data one wrote, but seeks/tells are of course not effective. Furthermore, you will find that some append modes will not work properly. Material will be appended, but the original soft EOF will not be removed. It is then not possible to read beyond the original material. I recomend always using binary mode unless you have a compelling reason to do otherwise. Your code will remain portable, as *nix systems will ignore the 'b' in arguments such as "wb" or "rb".
     
  5. bughunter2

    bughunter2 New Member

    Joined:
    Feb 27, 2007
    Messages:
    31
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Netherlands
    Home Page:
    http://reversemasters.nl/
    I just decided I'm going to use binary mode everywhere unless I need text mode, just like you do, thanks for great info :)

    It's great the UNIX (and alike) systems ignore the stupid (imo) text mode, and also keep the code portable by ignoring the 'b' mode.

    The Windows text mode read/writes are actually a lot like FTP transfers, files are converted to other system's EOF and line ending usages.

    Thanks for the info DaWei, you're a quick poster ;)
     
  6. DaWei

    DaWei New Member

    Joined:
    Dec 6, 2006
    Messages:
    835
    Likes Received:
    5
    Trophy Points:
    0
    Occupation:
    Semi-retired EE
    Location:
    Texan now in Central NY
    Home Page:
    http://www.daweidesigns.com
    You can make binary the Windows default by setting a global variable. I believe it's called _fmode. This would not help, of course, if your souce is compiled on a system with the text default. Quite frankly, the text mode thing is a serious bugaboo. The only time it is really necessary is when you are reading files written by another application. If you don't match that application's mode you will wind up with lines that don't wrap or lines that wrap twice, depending upon the direction of mismatch. The expected line endings for Windows, Mac, and *nix, for textual material, are CRLF, CR, and LF. It's unfortunate.
     
  7. bughunter2

    bughunter2 New Member

    Joined:
    Feb 27, 2007
    Messages:
    31
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Netherlands
    Home Page:
    http://reversemasters.nl/
    But then indeed, calls to fseek() can be confusing. I usually write my own string functions for correct parsing and text formatting to prevent confusing myself.

    I'm not even going to try to set the _fmode because I'd probably forget it when compiling on other computers.

    However, I'm still interested in how to set it? Is it an environment variable?
     
  8. DaWei

    DaWei New Member

    Joined:
    Dec 6, 2006
    Messages:
    835
    Likes Received:
    5
    Trophy Points:
    0
    Occupation:
    Semi-retired EE
    Location:
    Texan now in Central NY
    Home Page:
    http://www.daweidesigns.com
    It's just a global variable (extern int _fmode). One can just write "_fmode = _O_TEXT (or _O_BINARY). Since C++ 2005, though, it is recommended that one use _get_fmode and _set_fmode. You can also just link in Binmode.obj, which will set it to binary EXCEPT FOR operations involving stdin, stdout, and stderr.
     
  9. bughunter2

    bughunter2 New Member

    Joined:
    Feb 27, 2007
    Messages:
    31
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Netherlands
    Home Page:
    http://reversemasters.nl/

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice