掰碎了讲换行符和回车符

一开始对这个概念还只是有点模糊,不太在意,结果一搜索才发现,这东西太有意思了,不仅有个有趣的故事,而且本身也有很多门道,还勾起了一些之前的回忆,原来以前也跟这个问题打过交道啊。

1基本概念


控制字符


本义


换行符


\n


newline


LF (Line Feed)


光标直接往下一行(不一定是行首)


回车符


\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. (二进制情况下回车和换行的转换是不存在的).

时间: 2024-08-05 11:11:02

掰碎了讲换行符和回车符的相关文章

替换SQL字段中的换行符,回车符

有时候我们需要替换一些不需要的SQL字段, 下面就为您介绍替换SQL字段的几种情况,如果您对替换SQL字段方面感兴趣的话,不妨一看. 替换SQL字段中的换行符,回车符: 1> 回车符 SELECT *, REPLACE(detail, CHAR(13) , '<br>') AS 显示替换后的内容 FROM loginfo 2>换行符 SELECT *, REPLACE(detail, CHAR(10), '<br>') AS 显示替换后的内容 FROM loginfo

sqlserver数据库 去除字段中空格,换行符,回车符(使用replace语句)

SQL中可以使用Replace函数来对某个字段里的某些字符进行替换操作,语法如下: 语法 REPLACE ( original-string, search-string, replace-string ) 参数 如果有某个参数为 NULL,此函数返回 NULL. original-string     被搜索的字符串.可为任意长度. search-string     要搜索并被 replace-string 替换的字符串.该字符串的长度不应超过 255 个字节.如果 search-strin

ASP.NET弹出显示ex.Message异常信息 存在换行符和回车符处理办法。

1.把ex.Message换成任意字符串,检验在catch语句块中可以用Response.Write方法显示对话框.结果显示成功,说明问题就出在ex.Message上. 2.在程序中下断点,可以看到ex.Message的内容如下图: 重点是红色圈起来的部分,这里边有个回车+换行符号,估计也就是他搞的鬼,二话不说,直接把它去掉,代码如下: try {//…. }  catch (Exception ex) { Response.Write("<script language='javascr

oracle中去掉文本中的换行符、回车符、制表符

一.特殊符号ascii定义 制表符 chr(9)  换行符 chr(10) 回车符 chr(13) UPDATE tc_car_order set USE_REASON =  REPLACE('USE_REASON',chr(9),'');UPDATE tc_car_order set USE_REASON =  REPLACE('USE_REASON',chr(10),'');UPDATE tc_car_order set USE_REASON =  REPLACE('USE_REASON',

Windows、Unix、Mac不同操作系统的换行问题-剖析回车符\r和换行符\n

转载链接:http://blog.csdn.net/tskyfree/article/details/8121951 一.概念: 换行符‘\n’和回车符‘\r’ (1)换行符就是另起一行  --- '\n' 10 换行(newline) (2)回车符就是回到一行的开头 --- '\r' 13 回车(return) 所以我们平时编写文件的回车符应该确切来说叫做回车换行符     二.应用: (1)在微软的MS-DOS和Windows中,使用“回车CR('\r')”和“换行LF('\n')”两个字符

sql -- 移除数据中的换行符和回车符

--移除回车符 update master_location SET street_number = REPLACE(street_number, CHAR(13), '') --移除换行符 update master_location SET street_number = REPLACE(street_number, CHAR(10), '')

ORALCE 换行符 空格符 回车符

① 换行符 chr(10)② 回车符 chr(13) ③ 空格符 chr(9) 例1:效果对比.chr(10)在一个字段中换行显示一列数据,chr(13)同样是换行显示一行数据,chr(9)会显示一个空格.因此,需要在 oralce 的一个字段中同一列显示换行的两句话,在SQL语句中拼入 chr(10) 或者 chr(13) 都可以. 1 select '换行符1'||chr(10)||'换行符2'||chr(10)||'换行符3' from dual; 2 select '回车符1'||chr

掰碎了讲中文编码

  电脑用0和1存储数据,而存储的数据主要有两种:数字和字符(还有运算符什么的暂时不讨论),数字存储的方法比较简单,没什么问题,这里要说的是如何存储字符. 1编码方式的大历史 1.1  ASCII 最早对于发明计算机的美国人来说,字符只有大小写的字母,于是他们使用一种简单的编码方式——ASCII,一个字母对应一个8位二进制码(ASCII码),或者说数字0-255,或者说8比特,或者说1个字节.存储的内容其实就是这组8位01码,当使用ASCII编码方式的软件被告知用字符的方式显示这组8位01码时,

关于MYSQL表记录字段换行符回车符处理

UPDATE tablename SET  FIELD = REPLACE(REPLACE(FIELD, CHAR(10), ''), CHAR(13), ''); CHAR(10):  换行符 CHAR(13):  回车符