Why doesn't fwrite() write a Binary File using

2019-01-28 01:47发布

问题:

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.

回答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!



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



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



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



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



回答6:

Unix like OS treats both as same. I'm not sure this is the right answer, but if you want to put a text as hex into a file, try applying \x before the text.e.g. if you are trying to write hello into a file, you're buffer will be:
char *buf = "hello";
If you want to write hex of "hello" into the file, your buffer should be like this
char *buff = "\x68\x65\x6c\x6c\x6f";
Hope it helped