C语言学习笔记(4):回车与换行的区别


符号 ASCII 意义
\n 0x0A 换行(LF)
\r 0x0D 回车(CR)

    \r 是return的简写,表示光标重新回到本行开头。其缩写CR是carriage return就是回车的意思。

    \n 是new line的简写,表示光标垂直向下移动一行。其缩写LF是Line Feed就是换行的意思。

   在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33,Linux/Unix下的tty概念也来自于此)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。
   于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。这就是“换行”和“回车”的来历,从它们的英语名字上也可以看出一二。
   后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。
   Unix系统里,每行结尾只有“<换行>”,即"\n";

   Windows系统里面,每行结尾是“<换行><回车>”,即“\r\n”;

   Mac系统里,每行结尾是“<回车>”,即"\n";。

   一个直接后果是,Unix/Mac系统下的文件在 Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。

    于是,进行测试,分别在win10和ubuntu系统中新建文本文档写入两行文字:第一行为123456789,第二行为987654321。然后在win10系统中打开两个文本,发现win10自己创建的文件是分为两行显示的,没有问题。Ubuntu生成的文件在win10中显示为1行。接下来在Ubuntu中打开两个文件,发现两个文件均换行。接下来在win10系统中通过UltraEdit打开,查看两个文件的ASCII码,如下:

win10中生成的文件:

win

Ubuntu中生成的文件:

linux

    从结果可以看出,正如上面所说,Unix系统中,每行结尾只有”\n”;windows系统中每行结尾是”\r\n”。

    还没结束,接下来说一说在C语言编程中的”\n”,因为这里与上面说的又有不同。

#include <stdio.h>
#include <math.h>
#include <stdio.h>

FILE *fp;

void main()
{
    fp = fopen("p1.txt","wb");

    fprintf(fp, "123456789\n987654321");

    fclose(fp);

    return;
}

如上代码,fopen函数中,参数"wb"表示只写打开或新建一个二进制文件;只允许写数据。根据上面所提到的\n意义,我们推断在win10中,打开生成的txt文件,应该仅输出一行。实际情况也确实如此。接下来,我们把fopen中的参数改为fopen("p1.txt","wx");其余代码全不变,这里"wx"表示创建文本文件,只允许写入数据。其结果发现生成的txt中,存在两行,也就是说"\n"一个符号就完成了win10中的换行命令。这说明在C语言中输出文档时,若采用二进制编码输出文件,函数会严格按照给定字符串的编码来进行输出;但是如果设定输出文档时以文本形式输出,函数会自动将\n解析为\r\n,从而输出两行文本。这一点在控制台程序中也有体现:

#include <stdio.h>

void main()
{
    printf("Hello World!\n");
}

上面的代码显然会换行,并在第二行输出:Press any key to continue

再啰嗦一些,如果把第一段代码中fprintf(fp, "123456789\n987654321");改为fprintf(fp, "123456789\r\n987654321");并且采用"wx"输出,会怎么样呢?

嗯!首先肯定是会换行的。然后,我们参看它的ASCII,发现\r\n在文本中并不是像预期的那样是0D 0A而是0D 0D 0A:

这也说明了,在这里代码中的"\n"被fprintf函数解析输出为"\r\n"。当然如果在linux系统下执行这个程序,应该是会把"\n"仅解析为"\n"的。

嗯,然后也可以测试一下fprintf(fp, "123456789\r987654321");在"wb"和"wx"情况下的输出文本结果。嗯是完全一样的:123456789987654321

但是,如果在控制台上输出结果,例如:printf("123456789\r987654321");实际输出结果为:987654321,说明"\r"起作用,控制台先输出123456789,然后,"\r"使光标移动到最前方,输出987654321,将原来的输出覆盖。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM