写入以文本模式打开但在二进制模式下不会发生的文件时会发生什么转换?特别是在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);
答案 0 :(得分:42)
我相信大多数平台在处理流时会忽略“t”选项或“text-mode”选项。然而,在Windows上,情况并非如此。如果您在MSDN查看fopen()函数的描述,您将看到指定“t”选项将产生以下效果:
答案 1 :(得分:27)
在文字模式下,换行符“\ n”可能会转换为回车+换行符“\ r \ n”
通常你想要以二进制模式打开。尝试在文本模式下读取任何二进制数据将无法正常工作,它将被破坏。你可以在二进制模式下阅读文本,但它不会自动将“\ n”翻译为“\ r \ n”。
请参阅fopen
答案 2 :(得分:5)
此外,当您使用“rt”打开文件时,输入将在Crtl-Z字符上终止。
答案 3 :(得分:4)
另一个区别是使用fseek
如果流以二进制模式打开,则新位置恰好是从文件开头开始测量的偏移字节(如果origin是SEEK_SET),如果origin是SEEK_CUR,则从当前文件位置开始,如果是原点,则从文件末尾开始是SEEK_END。某些二进制流可能不支持SEEK_END。
如果流在文本模式下打开,则唯一支持的offset值为零(适用于任何原点)和早先调用std :: ftell在与同一文件关联的流上返回的值(仅适用于SEEK_SET的来源。
答案 4 :(得分:3)
我们在文本模式下打开文件时遇到了一个有趣的问题,其中文件中包含行尾字符的混合:
1\n\r
2\n\r
3\n
4\n\r
5\n\r
我们的要求是我们可以将当前位置存储在文件中(我们使用fgetpos),关闭文件然后重新打开文件并寻找该位置(我们使用fsetpos)。
但是,如果文件中包含行结尾的混合,则此过程无法寻找实际相同的位置。在我们的例子中(我们的工具解析C ++),我们重新阅读了我们已经看过的文件的部分内容。
使用二进制文件 - 然后您可以准确控制从文件中读取和写入的内容。
答案 5 :(得分:1)
尽管已经回答了这个问题并清楚地说明了这个问题,但我认为用一个简单的代码示例来显示主要问题(\ 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上执行逆转换。
答案 6 :(得分:0)
在“ w”模式下,文件以写模式打开,基本编码为“ utf-8” 在'wb'模式下,该文件以write -binary模式打开,可用于写入其他特殊字符,并且编码可以是'utf-16le'或其他