64

写入以文本模式打开而二进制模式不存在的文件时会发生什么转换?特别是在 MS Visual C 中。

unsigned char buffer[256];
for (int i = 0; i < 256; i++) buffer[i]=i;
int size  = 1;
int count = 256;

二进制模式:

FILE *fp_binary = fopen(filename, "wb");
fwrite(buffer, size, count, fp_binary);

与文本模式:

FILE *fp_text = fopen(filename, "wt");
fwrite(buffer, size, count, fp_text);
4

7 回答 7

60

我相信大多数平台在处理流时都会忽略“t”选项或“text-mode”选项。但是,在 Windows 上,情况并非如此。如果你看一下 fopen() 函数的描述:MSDN,你会看到指定“t”选项将产生以下效果:

  • 换行符 ('\n') 将在输出时转换为 '\r\n" 序列
  • 回车/换行序列将在输入时转换为换行。
  • 如果文件以追加模式打开,则将检查文件末尾是否有 ctrl-z 字符(字符 26),如果可能,删除该字符。它还将将该字符的存在解释为文件的结尾。这是从 CPM 时代起不幸的遗留物(关于父母的罪孽在他们的孩子身上被探视到第三代或第四代)。与之前陈述的观点相反,不会附加 ctrl-z 字符。
于 2008-10-23T18:28:30.017 回答
31

在文本模式下,换行符“\n”可以转换为回车+换行符“\r\n”

通常你会想要以二进制模式打开。试图以文本模式读取任何二进制数据都行不通,它会被损坏。不过,您可以在二进制模式下正常阅读文本 - 它只是不会将“\n”自动翻译成“\r\n”。

fopen

于 2008-10-23T14:30:54.897 回答
6

此外,当您使用“rt”打开文件时,输入以 Crtl-Z 字符终止。

于 2008-10-23T14:36:26.960 回答
5

另一个区别是使用时fseek

如果流以二进制模式打开,如果源是 SEEK_SET,则新位置正好是从文件开头测量的偏移字节,如果源是 SEEK_CUR,则从当前文件位置测量,如果源是 SEEK_END,则从文件末尾测量。一些二进制流可能不支持 SEEK_END。

如果流以文本模式打开,则唯一支持的 offset 值是零(适用于任何来源)和先前在与同一文件关联的流上调用 std::ftell 返回的值(仅适用于SEEK_SET 的来源。

于 2014-07-17T08:46:28.577 回答
3

我们在以文本模式打开文件时遇到了一个有趣的问题,其中文件混合了行尾字符:

1\n\r
2\n\r
3\n
4\n\r
5\n\r

我们的要求是我们可以将当前位置存储在文件中(我们使用 fgetpos),关闭文件,然后重新打开文件并寻找该位置(我们使用 fsetpos)。

但是,如果文件混合了行尾,则此过程无法找到实际的相同位置。在我们的例子中(我们的工具解析 C++),我们正在重新读取我们已经看到的部分文件。

使用二进制 - 然后您可以准确控制从文件中读取和写入的内容。

于 2008-10-23T17:32:16.340 回答
3

尽管这个问题已经得到解答并得到了清楚的解释,但我认为用一个简单的代码示例来展示主要问题(\n 和 \r\n 之间的翻译)会很有趣。请注意,我没有解决文件末尾的 Crtl-Z 字符的问题。

#include <stdio.h>
#include <string.h>

int main() {
    FILE *f;
    char string[] = "A\nB";
    int len;
    
    len = strlen(string);
    printf("As you'd expect string has %d characters... ", len); /* prints 3*/
    f = fopen("test.txt", "w"); /* Text mode */
    fwrite(string, 1, len, f);  /* On windows "A\r\nB" is writen */
    printf ("but %ld bytes were writen to file", ftell(f)); /* prints 4 on Windows, 3 on Linux*/ 
    fclose(f);
    return 0;
}

如果您在 Windows 上执行该程序,您将看到打印以下消息:

As you'd expect string has 3 characters... but 4 bytes were writen to file

当然,您也可以使用 Notepad++ 之类的文本编辑器打开文件,然后查看自己的字符:

在此处输入图像描述

在以文本模式读取文件时,在 Windows 上执行逆变换。

于 2020-10-11T16:32:36.437 回答
0

在'w'模式下,文件以写模式打开,基本编码是'utf-8',在'wb'模式下,文件以写-二进制模式打开,负责写入其他特殊字符和编码可能是 'utf-16le' 或其他

于 2019-11-09T07:09:02.523 回答