16

What is the different between these blocks of code. I tried to search for "wb" but don't see it anywhere. The file containing "wb" is from on of my tutors

FILE *f = fopen(DB_FILE_NAME, "wb");
    if (f == NULL) {
        printf("Write error\n");
    } else {
        /* write n_students elements of the studentlist array */
        fwrite(studentlist, sizeof(student_t), n_students, f);
        fclose(f);
    }  

and

FILE *f = fopen(DB_FILE_NAME, "w");
    if (f == NULL) {
        printf("Write error\n");
    } else {
        /* write n_students elements of the studentlist array */
        fwrite(studentlist, sizeof(student_t), n_students, f);
        fclose(f);
    }
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Anh Minh Tran
  • 341
  • 1
  • 3
  • 11

4 Answers4

20

Specifying "b" in the access mode prevents (some implementations of) the standard library from translating a few characters when reading/writing to the file.

Most common translation is for end of line: \n is translated to \r\n in Windows.

pmg
  • 106,608
  • 13
  • 126
  • 198
  • 2
    This actually answers the question. Thank you! It is hilarious that other people quote the documentation that fails to state this fact... (Just discovered that writing structs with 'w' corrupts data...) – thehorseisbrown Feb 12 '20 at 16:46
15

Absolutely any reference on the fopen() function would have told you this. For instance the manual page which is the common documentation used in Unix-like environments:

The mode string can also include the letter 'b' either as a last character or as a character between the characters in any of the two-character strings described above. This is strictly for compatibility with C89 and has no effect; the 'b' is ignored on all POSIX conforming systems, including Linux. (Other systems may treat text files and binary files differently, and adding the 'b' may be a good idea if you do I/O to a binary file and expect that your program may be ported to non-UNIX environments.)

So, it stands for binary and is useful to indicate that you intend to treat the contents of the file as not being text.

For your code, binary access seems right. However, directly writing raw struct values is generally a very bad idea, since you don't know the exact internal format used by the compiler and it can change unexpectedly. For files that should be shared and/or accessed "later", this is not the proper way to do it in C. Look into serialization.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 1
    So if I added "B", the file would be treated as binary and if not, it would be treated as text? By the way can you tell me the role of "f" in FILE *f? – Anh Minh Tran May 04 '17 at 08:49
  • https://www.securecoding.cert.org/confluence/display/c/FIO14-C.+Understand+the+difference+between+text+mode+and+binary+mode+with+file+streams – David Ranieri May 04 '17 at 08:54
  • 3
    @AnhMinhTran The `f` is simply the variable name, and `FILE *` ("pointer to `FILE`") is the variable's type. This is basic C syntax, and if that feels unfamiliar you really need to study the language more. – unwind May 04 '17 at 08:56
  • I disagree with this comment. I have VERY different behavior when opening with "w" vs. "wb". In my case, I am writing floating point values directly to a file. – Jiminion Jan 12 '18 at 19:37
6

In fopen documentation :

With the mode specifiers above the file is open as a text file. In order to open a file as a binary file, a "b" character has to be included in the mode string. This additional "b" character can either be appended at the end of the string (thus making the following compound modes: "rb", "wb", "ab", "r+b", "w+b", "a+b") or be inserted between the letter and the "+" sign for the mixed modes ("rb+", "wb+", "ab+").

Badda
  • 1,329
  • 2
  • 15
  • 40
0

replace "wb" with "wb+"