Why doesn't fwrite() write a Binary File using "wb", in C, on Mac OS X?

14,145

Solution 1

All files are binary.

The difference between "text files" and "binary files" in the context of fopen is that the standard library may use a filter for reading and writing the file when in text mode. In binary mode, what you write is always what is written.

The only practical example I know of is in Windows, where opening a file in text mode will make it convert between Windows-style line endings (CRLF, "\r\n") and C-style/Unix-style line-endings (LF, "\n"). For example when you open a file for reading in Windows in text mode, line endings will appear as "\n" in your program. If you were to open it in binary mode, line endings would appear as "\r\n" in your program.


You can also inspect your file with cat, for example:

cat filename

You should get the output: I am a string!

Solution 2

Both files are binary files. They're an exact copy of the data you sent to fwrite. Some broken operating systems have text files which are not binary; they have extra junk like \r\n replacing \n, or fixed-size line records, etc. POSIX forbids all of this. On any POSIX OS, text and binary mode are identical.

By the way, "wt" is not a valid mode argument to fopen. Text mode is default. The t modifier to request text mode is an extension of broken Windows implementations where binary is default but text mode is available by request.

Solution 3

The only difference text mode makes it to line endings. So, if you fprintf a \n it will be translated according to platform. For your example, binary or text mode makes no difference to what is written to the file.

Solution 4

On most Unix-like systems, there's no difference between opening a file in text vs. binary mode. In addition, the data you're writing above wouldn't show a difference even on many systems that do treat "text" and "binary" files differently.

Just for example, on Windows opening a file in text mode typically means that a "\n" that you write will be translated to "\r\n" in the actual file (and during reading the opposite is done). Since you haven't written a "\n", that translation wouldn't happen.

Solution 5

You're right. This doesn't matter on Unix-like systems. Discussion from the cygwin camp. What difference did you expect to see? You are writing ASCII text to a file, not arbitrary binary data.

Share:
14,145
Dave
Author by

Dave

Updated on June 04, 2022

Comments

  • Dave
    Dave almost 2 years

    For the sake of learning C and understanding the difference between Binary Files and Text Files, I'm attempting to write a string to file as both file types like so:

    char * string = "I am a string!";
    
    FILE * filePtrA = fopen("/output.txt", "wt");
    fwrite(string, strlen(string), 1, filePtrA);
    
    FILE * filePtrB = fopen("/output.bin", "wb");
    fwrite(string, strlen(string), 1, filePtrB);
    
    fclose(filePtrA);
    fclose(filePtrB);
    

    However both "wt" and "wb" are writing as a Text File, where "wb" should be writing as a Binary File. Hex appears like so for both files:

    49 20 61 6D 20 61 20 73 74 72 69 6E 67 21
    

    Why is this happening, and how can I write something as a Binary File?

    I have read that the OS (Mac OS X 10.6 - GCC 4.2) might not differentiate between Binary and Text Files, though I'm still stumped why a hex editor wouldn't detect any difference.

    • Vovanium
      Vovanium over 13 years
      I wonder what you're expected to see in "binary" file?
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE over 13 years
    Replace "most" with "all". POSIX requires text mode and binary mode to be identical. This is so fundamental that I don't think you could consider any OS which fails to be "Unix-like".
  • mrivard
    mrivard over 13 years
    To clarify; The angle brackets around "filename" were just meant to illustrate that it is a variable, not something to copy verbatim. So replace the string <filename> by the actual filename, and you should be good :)
  • caf
    caf over 13 years
    Versions of Mac OS prior to OS X used \r to denote line-endings, so the text-mode/binary-mode distinction was relevant there too.
  • Zulan
    Zulan about 8 years
    In memory, both buff are exactly the same. There is no difference.
  • fluffybunny
    fluffybunny about 8 years
    Yes, but the difference is when you write it into the file. In first case "hello", it will be written as text in the file, while "\x68\x65\x6c\x6c\x6f" will be written as hex in the file not text
  • Zulan
    Zulan about 8 years
    That is wrong. Since there is no difference in memory, fwrite just writes an identical block of data to a file. You need to use \x only for characters that cannot be directly encoded in the source file. Just try it.
  • M.M
    M.M about 7 years
    What implementations have binary as default mode? My experience has always been text mode is the default (and, in MS C, t modifier is redundant but people use it for clarity)
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE about 7 years
    @M.M: Text mode is always the default mode; this is required by ISO C. POSIX requires text mode and binary mode to be identical so it doesn't matter.