C语言中以文本方式读写文件时换行符转换的注意事项

我们知道在UNIX下是没有回车符( )的,只有换行符( ),而C语言诞生于UNIX(Linux即面向开源的UNIX,Mac OS也是UNIX发展而来的,而Windows是从MS-DOS发展而来,与前两者不同),所以C语言的源代码文件中也是以 表示换行。

所以总结一下:

Windows下换行采用 表示,全称回车换行符。

UNIX(Linux)下换行采用 表示,即换行符。

Mac OS下换行采用 表示,即回车符。

所以,当C语言在Windows下以文本方式读取文件就会出现一个转换,看如下代码:

FILE * f1;
f1 = fopen("utf8.txt", "r");
/*
    "utf8.txt"文件的十六进制结构如下:
    41 42 43 0D 0A 44 44 4B
*/
fseek(f1, 3, SEEK_SET);
printf("%x
", getc(f1));
printf("%x
", getc(f1));
fclose(f1);

输出结果:

a
44
Press any key to continue

解释:当我们把文件指针通过fseek函数移到位置 3 时,文件指针指向了回车符(0x0D),然后我们用getc函数读取当前文件指针所指的字节时,C语言会把Windows下表示换行的0x0D和0x0A两个字节看成UNIX下表示换行的0x0A一个字节,所以,此时getc函数返回的是0x0A这个值。故,这次的getc函数读完后文件指针向后偏移两个字节,导致了下一个的getc返回的是0x44。

同理,当C语言在Windows下工作时,用putc向文件输入 时会被自动转成 ,如下代码:

FILE * f1;
f1 = fopen("new.txt", "w");
putc('
', f1);
fclose(f1);

"new.txt"文件的十六进制结构:

0D 0A

解释:上述代码会在当前目录创建一个新文件"new.txt",并以文本方式只写模式打开文件流,然后通过putc向该文件输入字符 ,这时C语言会自动把 转为 ,原理同上。

注意的是:C语言是否自动转换 与 取决于编译C语言程序时所在的系统,也同理在Mac OS下,C语言会自动发生 与 的转换。

当然,这种情况是不会发生转换的:

FILE * f1;
f1 = fopen("utf8.txt", "r");
/*
    该文件的十六进制结构如下:
    31 32 33 0A 0D
*/
fseek(f1, 3, SEEK_SET);
printf("%x
", getc(f1));
printf("%x
", getc(f1));
fclose(f1);

输出结果:

a
d
Press any key to continue

解释:因为只有在Windows下编译的C程序,并且以文本方式打开一个文件,并且读取的0x0D后面紧跟着0x0A才会发生转换,也就是说0x0D 0x0A两个字节必须作为一个整体出现,显然,上述代码例子颠倒了 的顺序。

另外,在Mac OS下编译的C程序,以文本方式读取一个以 表示换行的文件时,也是不会发生 与 的转换的,只有该文件以 表示换行时才会发生  与 的转换。

原文地址:https://www.cnblogs.com/ryzz/p/9358337.html