文件访问模式"w"和"wb"的区别

18
这些代码块有何区别?我试图查找“wb”,但没有找到。包含“wb”的文件来自我的一位导师。

这些代码块有何不同?我尝试搜索“wb”,但未在任何地方找到它。包含“wb”的文件来自我的一位导师。

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);
    }  
并且
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);
    }
4个回答

22

在访问模式中指定 "b" 可以防止(一些实现的)标准库在读/写文件时转换几个字符。

最常见的转换是针对行尾:在 Windows 中,\n 转换为 \r\n


2
这实际上回答了问题。谢谢!其他人引用未能说明这一事实的文档,这真是太有趣了...(刚刚发现使用“w”编写结构会破坏数据...) - thehorseisbrown

16
任何关于 fopen() 函数的参考资料都会告诉你这一点。例如,在类 Unix 环境中使用的常见文档手册页

模式字符串还可以包括字母“b”,它既可以作为最后一个字符,也可以作为任意两个字符字符串中的字符之间的字符。这仅仅是为了与 C89 兼容,并且没有任何影响;在包括 Linux 在内的所有符合 POSIX 标准的系统上,“b” 都会被忽略。(其他系统可能会对文本文件和二进制文件进行不同的处理,如果你需要进行 I/O 操作到一个二进制文件并且希望你的程序可能被移植到非 UNIX 的环境中,添加“b”可能是个好主意。)

因此,它代表二进制 (binary),有助于表明你打算将文件内容视为非文本。
对于你的代码,二进制访问似乎是正确的。然而,直接写入原始的 struct 值通常是一个非常糟糕的想法,因为你不知道编译器使用的确切内部格式,它可能会意外更改。对于应该共享和 / 或“稍后”访问的文件,在 C 中这不是正确的方法。研究序列化。

1
如果我添加了“B”,那么文件将被视为二进制文件,否则它将被视为文本文件?顺便问一下,您能告诉我 FILE *f 中“f”的作用是什么吗? - Anh Minh Tran
https://www.securecoding.cert.org/confluence/display/c/FIO14-C.+Understand+the+difference+between+text+mode+and+binary+mode+with+file+streams - David Ranieri
3
f只是变量名,FILE *(指向FILE的指针)是变量的类型。这是基本的C语法,如果不熟悉的话,您需要更多地学习这门语言。 - unwind
我不同意这个评论。使用"w"和"wb"打开文件时,我的行为非常不同。在我的情况下,我直接将浮点值写入文件。 - Jiminion

6
fopen文档中:
使用以上模式指示符,打开的文件将会作为文本文件打开。如果要以二进制文件形式打开文件,需要在模式字符串中包含一个“b”字符。这个额外的“b”字符可以附加在字符串末尾(从而生成以下复合模式:“rb”、“wb”、“ab”、“r+b”、“w+b”、“a+b”),也可以插入到字母和“+”号之间以形成混合模式(“rb+”、“wb+”、“ab+”)。

0

将 "wb" 替换为 "wb+"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接