一开始对这个概念还只是有点模糊,不太在乎,结果一搜索才发现,这东西太有意思了,不只有个有趣的故事,并且自己也有不少门道,还勾起了一些以前的回忆,原来之前也跟这个问题打过交道啊。html
1基本概念python
|
|
|
控制字符linux |
本义c++ |
换行符web |
\n编程 |
newlinewindows |
LF (Line Feed)编辑器 |
光标直接往下一行(不必定是行首)ide |
回车符编码 |
\r |
return |
CR(Carriage Return) |
光标从新回到本行开头 |
基本概念如上表所示。
2由来
为何会有这两个东西呢?它有一个有趣的传说:在计算机尚未出现以前,有一种叫作电传打字机(Teletype Model 33)的玩意,每秒钟能够打10个字符。可是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好能够打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。
因而,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫作“回车”,告诉打字机把打印头定位在左边界;另外一个叫作“换行”,告诉打字机把纸向下移一行。
这个分秒级的传说没有考证,可是确实,看名字也能知道换行符确实是用来将打字纸滚动一行,回车符是用来将打印头移到行开头也就是左边界。如当前位置是第5行第6个字符,那么回车是当前位置变成第5行第1个字符,而换行是当前位置变成第6行第6个字符位置,这样在打字机上打印时,只要回车而不换行,就能够在同一行上重复打印字符。
3如今状况
后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就能够。因而,就出现了分歧:
\n: UNIX系统/MAC OS X系统行末结束符
\r: MAC OS系统行末结束符
\n\r: windows系统行末结束符
也就是说在计算机上,其实只须要一个符号表示这行已经结束,光标移向下一行行首。大部分系统采用了直接使用换行符\n也就是纸滚转一行的方式,只有windows以为按照传统来,用两个符号表示光标移向下一行行首比较稳当。
而ENTER键的定义是直接配合操做系统的,若是是UNIX就单是\n,windows就是\n\r,总之实现一个换行功能。另外,其实这里说的换行符跟word中的段落标记^p是同样的。
4问题来了
诶,这里问题就来了,既然UNIX系统中\n彻底表示换行回车,那么其中\r表示什么呢?这个我并不关心。
另外既然windows系统\n\r表示换行回车,那么单独的\n和\r就仍是本来的意思即换行和回车么?
这个问题咱们就能够探究一下了。
如何探究,其实这也有个问题,以前没有想到,后来出问题了查了半天才明白。
由于我若是在windows系统中的txt文档中直接写\n,它会被当成两个字符读取的,并无转义的功能,因此我准备的探究方式是经过程序向文档写入字符,这个写入的字符中没有天然换行回车,全部换行回车都是显性表示,这样咱们把其余字符和单独的\n和\r和\n\r写入windows系统中的txt文档,就能够观察到windows系统中单独的\n和\r各表示什么。
接下来我我进行了实验,并对着实验结果陷入了深深思考,终于发觉了哪儿有问题。
这个设想的探索方案看起来很清晰可行,可是其实它创建在咱们的一个假设上:当咱们经过程序向文档写入字符时,咱们认为程序会原本来本地把咱们写入的字符串 ’这是第一行\n\r这是第二行\n这是长一些的第三行\r这是第四行’ 先用GBK编码成01码,而后把这段01码写入文本文档,而后当咱们打开文本文档的时候,文本文档把这段01码用GBK解码并显示出来。
5实验结果和分析
但实验结果告诉咱们可能并非这样,由于个人实验结果是这样的:
1)对于\r,win7.txt不识别(就当没有同样)
2)对于\n,win7.txt识别,执行结果是:换行回车
3)对于\n\r(和\r\n),win7.txt识别,执行结果是:换行回车(很容易理解,当\r不存在直接实现\n)
这个跟设想的好像不同,后来找到了一个可能的解释:在Windows环境中,若是输入到文本文件,在编码时,程序中的一个'\n'换行符被解释成'\r'、'\n'两个字符;相反,若是读取文本文件,文件中的相邻的两个'\r'、'\n'会合并为一个'\n'输出(这是发生在转码的时候吗)。
而此时我顺便用程序传输法作实验看了下对于python控制台输出和wxpython的文本框窗口,都是如何识别程序传送的'\r'、'\n'和’ \n\r’的。必须声明,包括上面的结果,这样子的状况都是通过程序润色的,第6节会有一些真实状况的参考。
5.2 python控制台输出
1)对于\r,识别,执行结果是:把光标移到当前这行的行首,若是接下来是字符,会同时删去这行全部字符,开始显示接下来的字符,若是接下来是\n,这行文字不会被删掉,光标到下一行行首(也就是说\r后面的字符会直接覆盖上一行字符,也就是上一个\n以前的字符)
2)对于\n,识别,执行结果是:换行回车
3)对于\n\r,识别,执行结果是:换行回车(很容易理解,当\n执行时,光标换行回车,再执行\r后,什么事情其实都没有作)
4)对于\r\n,识别,执行结果是:换行回车,就是上面提到\r接下来是\n的状况,不删字符而后换行
5.3 wxpython的文本框窗口(单行文本框)
1)对于\r,识别,执行结果是:出现一个看不到的空格,并且光标停在这个空格后面,能够往前删除掉它
2)对于\n,识别,执行结果是:出现一个看不到的空格,并且光标停在这个空格后面,能够往前删除掉它
3)对于\n\r(和\r\n),识别,执行结果是:出现两个看不到的空格,并且光标停在这两个空格后面,能够往前删除掉它
5.4 wxpython的文本框窗口(多行文本框)
1)对于\r,识别,执行结果是:换行回车
2)对于\n,识别,执行结果是:换行回车
3)对于\n\r,识别,执行结果是:两个换行回车
4)对于\r\n,识别,执行结果是:1个换行回车(这个有点怪。。)
6真实状况
0)在Windows中:
'\r' 回车,回到当前行的行首,而不会换到下一行;
'\n' 换行,换到当前位置的下一行,而不会回到行首;
1)Unix/Mac系统下的文件在Windows里打开,全部文字会变成一行
2)Windows里的文件在Unix/Mac下打开,在每行的结尾可能会多出一个^M符号
3)Linux保存的文件在windows上用记事本看的话会出现黑点
4)在linux下,命令unix2dos 是把linux文件格式转换成windows文件格式,命令dos2unix 是把windows格式转换成linux文件格式。
5)在不一样平台间使用FTP软件传送文件时, 在ascii文本模式传输模式下, 一些FTP客户端程序会自动对换行格式进行转换. 通过这种传输的文件字节数可能会发生变化。 若是你不想ftp修改原文件, 可使用bin模式(二进制模式)传输文本。
6)一个程序在windows上运行就生成CR+LF换行格式的文本文件,而在Linux上运行就生成LF格式换行的文本文件。
7其余
1)
在C语言里回车和换行是两个概念,回车是指光标由行中任意位置移动到行首,换行指换到下一行的状况。
第二个以及之后的多个(个数不定)的参数:后面的参数是用来告诉计算机在前面的%d占位符上将输出值得变量名。
咱们作一个试验:printf("hello") ;
输出结果:helloPress any key to continue ...
你们会看到,这时没有了回车换行,Press any key to continue ...就跑到上一行了。
对于回车的格式有单独的格式符\r
例如:printf("abcde\rf\n");他的输出就为:
fbcde
press any key to continue ...
实际上,计算机先输出:
abcde_ (注意“_”表明光标的位置)
而后,遇到\r格式符:
abcde (注意此时,光标在字母a的下方)
在而后,输出f和\n(回车换行)
fbcde (注意此时字母f把字母a覆盖掉了)
_ (这时,光标在下一行的行首)
紧跟着,Vc++集成环境输出Press any key to continue ...字符串。
2)软硬回车
硬回车就是普通咱们按回车产生的,它在换行的同时也起着段落分隔的做用。
软回车是用 Shift + Enter 产生的(在word中看到这个样子↓,在替换中名字叫手动换行符^l),它换行,可是并不换段,即先后两段文字在 Word 中属于同一“段”。在应用格式时你会体会到这一点。
咱们经常使用的回车是硬回车,就是在word中敲击Enter键产生的那个弯曲的小箭头,占两个字节。这种回车能够有效地把段落标记出来分清楚。在两个硬回车之间的文字自成一个段落,能够对它单独设置段落标记而不用担忧其余段落受到影响。这也是咱们习惯用硬回车的缘由:排版方便。
可是硬回车也给咱们带来了麻烦。你若是是网页设计者,或者是论坛游侠,必定有这样的经历:当你打算换行时,换出的行却实在不能恭维,行间距太大了!其实这和硬回车的原理是同样的,只不过在word等文本编辑器中没有显示出它的“原本面目”。不过这样的排版的确形成了不小的困难,这时咱们就得请出硬回车的兄弟:软回车。
软回车只占一个字节,在word中是一个向下的箭头。若是你从很复杂的网页中向word中复制过文字的话,对它必定不会陌生。可是想在word中直接输入软回车可不是那么容易的。由于软回车不是真正的段落标记,它只是另起了一行,不是分段。因此它不是很利于文字排版,由于它没法做为单独的一段被赋予特殊的格式。可是尽管如此,它在网页设计中仍是具备举足轻重的地位的。
软回车能使先后两行的行间距大幅度缩小,由于它不是段落标记,要和法定的段落标记——硬回车区别出来。硬回车的html代码是<p>..</p>,段落的内容就夹在里面,而软回车的代码很精悍:<br>。所以在网页中想用到软回车,只需切换到代码页面,键入软回车的代码便可。
下面我讲一下不一样编辑器文字互相拷贝时回车的转化状况。
地球人都知道的,网页的文字若是复制到word中,则硬回车变为弯曲的箭头,软回车变为向下的箭头。结果形成习惯用word编辑文本的朋友很不习惯很不舒服的状况。
word中的文本复制到网页中也是一样的道理。能够说word和网页比较兼容的,要不怎么会有“保存为web页”这种选项呢?
记事本也是你们摸的比较多的编辑器。可是近年来随着社会发展外加记事本的种种弊端,许多人都将其打入冷宫。对此我只能表示遗憾,由于记事本自己的功能不丰富就是别的编辑器所取代不了的优势。你们再次将网页的文字复制时,不妨粘贴到记事本里试试。哈哈,无论网页设计者用的是什么回车,如今都变成一种回车了!怎么,你不信?那就看看吧:软回车变成了普通的回车,硬回车变成了两个普通的回车。你再从记事本里复制文字到word,记事本里的回车无一例外全都变成了硬回车!你再再从记事本里复制文字到网页编辑器,全部回车就都变成软回车了!!
3)再谈文件操做时对换行回车的处理
在编程时文件操做 wb(二进制方式)或者wt(文本方式)也会有影响。我作了个实验(实验用.net2003) 在01.txt文件中输入12而后enter,在ultraedit中看到的二进制是31 32 0d 0a 而后程序以下: int mian() { FILE *fp1,*fp2,*fp3,*fp4,*fp5,*fp6; char a[10]; char b[10]; fp1 = fopen("01.txt","r"); fp3 = fopen("02.txt","w"); fread(a,sizeof(unsigned char),8,fp1); //a里是31 32 0a fwrite(a,sizeof(unsigned char),8,fp3); //02.txt里是31 32 0d 0a ,缘由是输入的状况下,换行回车转换成换行,而后输出时换行又会转成换行回车 fclose(fp1); fclose(fp3); fp2 = fopen("01.txt","rb"); fp4 = fopen("03.txt","wb"); fread(b,sizeof(unsigned char),8,fp2); //b里是31 32 0d 0a fwrite(b,sizeof(unsigned char),8,fp4); //03.txt里是31 32 0d 0a ,缘由是二进制状况下回车和换行的(相似文本方式的那种转换)是不存在的 fclose(fp2); fclose(fp4); return 0; } 好像结论是这样的:读的方式下,在文本方式下,enter是0x0a;在二进制方式下,enter是0x0d,0x0a。 MSDN中查到这样的话:Also, in text mode, carriage return–linefeed combinations are translated into single linefeeds on input, and linefeed characters are translated to carriage return–linefeed combinations on output. (输入的状况下,换行回车转换成换行,而后输出时换行又会转成换行回车)When a Unicode stream-I/O function operates in text mode (the default), the source or destination stream is assumed to be a sequence of multibyte characters. Therefore, the Unicode stream-input functions convert multibyte characters to wide characters. For the same reason, the Unicode stream-output functions convert wide characters to multibyte characters. Open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed. (二进制状况下回车和换行的转换是不存在的).