回车换行区别
2015-09-14 09:54
225 查看
回车与换行的区别
符号 ASCII码 意义
\n 10 换行NL
\r 13 回车CR
回车 \r 本义是光标重新回到本行开头,r的英文return,控制字符可以写成CR,即Carriage Return
换行 \n 本义是光标往下一行(不一定到下一行行首),n的英文newline,控制字符可以写成LF,即Line Feed
在不同的操作系统这几个字符表现不同,比如在WIN系统下,这两个字符就是表现的本义,在UNIX类系统,换行\n就表现为光标下一行并回到行首,在MAC上,\r就表现为回到本行开头并往下一行,至于ENTER键的定义是与操作系统有关的。通常用的Enter是两个加起来。
在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。
于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。
这就是“换行”和“回车”的来历,从它们的英语名字上也可以看出一二。
后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。
/*======================================*/
\n: UNIX 系统行末结束符
\n\r: window 系统行末结束符
\r: MAC OS 系统行末结束符
/*======================================*/
一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。(这也是经常说见到的现象,哈哈,原来是这样的)
c++语言编程时(windows系统)\r 就是return 回到 本行 行首 这就会把这一行以前的输出 覆盖掉
如:
int main() {
cout << "hahaha" << "\r" << "xixi" ;
}
最后只显示 xixi 而 hahaha 被覆盖了
\n 是回车+换行 把光标 先移到 行首 然后换到下一行 也就是 下一行的行首拉
int main() {
cout << "hahaha" << "\n" << "xixi" ;
}
则 显示
hahaha
xixi
字符编码:
=================
文字是人类的语言,对于计算机来讲,语言就是0和1而已,因此将字符保存在计算机里就会涉及到字符编码的问题。网上有许多文章和博客介绍不同字符编码方式,这里就不引用了。列一些我自己理解的重点:
ASCII:ANSI
最初的计算机存储有限,字符的存储使用的是8位的ASCII码(最高位为0),最多可以存储128个字符,加上扩展ASCII码(最高位为1)也只能存储256个字符。于是,各国都制定了自己的兼容ascii编码规范,就是各种ANSI码,来表示不同的语言中的不同文字。于是同样的ASCII码在不同的字符集(Collation/CharSet/Code Page)上就可以表示不同的字符,这就是为什么ANSI字符一定要与特定的Collation绑定才能表示唯一正确的字符,绑定错了就可能出现乱码(ascii码小于128的字符不会乱码)。
Unicode
又名万国码,所有语言的所有字符都可以用唯一的Unicode码来标识。Unicode有几种不同的实现方式:
- UTF-8: 按照字节(8位)来存储编码,长度可变(1~6字节)。完全兼容ascii码,即标准ascii码中的字符在unicode中也是以相同的码来表示的。UTF-8 使用第一个字节确定字节数:第一个字节首为0即一个字节,110即2字节,1110即3字节,字符后续字节都用10开始。
- UTF-16 (UCS2):按照双字节存储字符,因此有字节序问题:即高位在前(Big Endian)还是低位在前(Little Endian)。这个行为与CPU处理字节方式有关,一般Little Endian用得比较多。比如“汉”字,Unicode码为0x6C49,按照Big Endian存储就是6C49,Little Endian则为496C。
如何区分不同编码的文件:
用UltraEdit或者类似编辑器打开文本文件,切换到Hex Mode(ctrl + h),看文件头:
- 没有任何特殊文件头的,直接第一个字符就是文本内容的,是ansi文件
- 以BOM (Byte Order Mark) 开头的是否Unicode文件。BOM可以是0xFEFF(表示Big Endian)、0XFFFE(表示Little Endian)、或者0xEFBBBF (UTF-8)。注意,在Windows上用Notepad保存一个UTF-8的文件,也是以0xFFFE开头的。
Unicode与SQL Server:
================
UTF-8是目前使用最广泛的Unicode编码格式,但是SQL Server使用的是UTF-16作为Unicode字符的编码格式,即NCHAR/NTEXT/NVARHCAR存储的都是双字节编码的Unicode字符,以N为前缀(比如N'Hello')的字符串即为双字节Unicode字符。对于UTF-8字符串,如果它只包含ANSI字符,则可以按照ANSI串处理;否则的话必须将UTF-8串转换成UTF-16、再交给SQL
Server 处理。这种行为可能带来两个常见的问题:
- 许多程序(包括ASP.NET)在输出文件的时候都使用UTF-8格式。如果这些文件需要被SQL Server正确地处理,必须进行转码至UTF-16。
- SQL 2005以后支持对Native XML进行处理,但是如果XML文档本身是UTF-8编码,就没办法直接处理。下面是一个例子:
在SSMS中运行如下代码,会得到错误9420:
DECLARE @Inf XML
SET @Inf = '<?xml version="1.0" encoding="utf-8"?>
<root>
<names>
<name>高</name>
</names>
<names>
<name>帅</name>
</names>
</root>
'
SELECT x.value('name[1]', 'VARCHAR(10)') AS Name
FROM @Inf.nodes('/root/names') AS t(x)
即使在给@Inf 赋值时强制指定N前缀转换成Unicode也不行,因为XML文档本身指定了UTF-8编码,解决的方法只有在XML文档中指定UTF-16编码并且指定N前缀:
DECLARE @Inf XML
SET @Inf = N'<?xml version="1.0" encoding="utf-16"?>
<root>
<names>
<name>高</name>
</names>
<names>
<name>帅</name>
</names>
</root>
'
SELECT x.value('name[1]', 'VARCHAR(10)') AS Name
FROM @Inf.nodes('/root/names') AS t(x)
关于看不见的字符0x1D
====================
这个字符为GROUP SEPARATOR,作用是分组,怎么用这个控制字符取决于应用程序。在MS SQL和SSIS中,这个字符并没有特别含义;但是Netezza确实把这个字符当作分隔符使用,导致在数据导入时分栏错误。遗憾的是Netezza的EXTERNAL TABLE导入时没办法控制batch size,所以排查这种问题比较麻烦。对于控制字符,可以在引用EXTERNAL DataSource的时候加上CTRLCHARS
TRUE选项,则可以将控制字符作为字段内容录入。
符号 ASCII码 意义
\n 10 换行NL
\r 13 回车CR
回车 \r 本义是光标重新回到本行开头,r的英文return,控制字符可以写成CR,即Carriage Return
换行 \n 本义是光标往下一行(不一定到下一行行首),n的英文newline,控制字符可以写成LF,即Line Feed
在不同的操作系统这几个字符表现不同,比如在WIN系统下,这两个字符就是表现的本义,在UNIX类系统,换行\n就表现为光标下一行并回到行首,在MAC上,\r就表现为回到本行开头并往下一行,至于ENTER键的定义是与操作系统有关的。通常用的Enter是两个加起来。
在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。
于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。
这就是“换行”和“回车”的来历,从它们的英语名字上也可以看出一二。
后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。
/*======================================*/
\n: UNIX 系统行末结束符
\n\r: window 系统行末结束符
\r: MAC OS 系统行末结束符
/*======================================*/
一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。(这也是经常说见到的现象,哈哈,原来是这样的)
c++语言编程时(windows系统)\r 就是return 回到 本行 行首 这就会把这一行以前的输出 覆盖掉
如:
int main() {
cout << "hahaha" << "\r" << "xixi" ;
}
最后只显示 xixi 而 hahaha 被覆盖了
\n 是回车+换行 把光标 先移到 行首 然后换到下一行 也就是 下一行的行首拉
int main() {
cout << "hahaha" << "\n" << "xixi" ;
}
则 显示
hahaha
xixi
字符编码:
=================
文字是人类的语言,对于计算机来讲,语言就是0和1而已,因此将字符保存在计算机里就会涉及到字符编码的问题。网上有许多文章和博客介绍不同字符编码方式,这里就不引用了。列一些我自己理解的重点:
ASCII:ANSI
最初的计算机存储有限,字符的存储使用的是8位的ASCII码(最高位为0),最多可以存储128个字符,加上扩展ASCII码(最高位为1)也只能存储256个字符。于是,各国都制定了自己的兼容ascii编码规范,就是各种ANSI码,来表示不同的语言中的不同文字。于是同样的ASCII码在不同的字符集(Collation/CharSet/Code Page)上就可以表示不同的字符,这就是为什么ANSI字符一定要与特定的Collation绑定才能表示唯一正确的字符,绑定错了就可能出现乱码(ascii码小于128的字符不会乱码)。
Unicode
又名万国码,所有语言的所有字符都可以用唯一的Unicode码来标识。Unicode有几种不同的实现方式:
- UTF-8: 按照字节(8位)来存储编码,长度可变(1~6字节)。完全兼容ascii码,即标准ascii码中的字符在unicode中也是以相同的码来表示的。UTF-8 使用第一个字节确定字节数:第一个字节首为0即一个字节,110即2字节,1110即3字节,字符后续字节都用10开始。
- UTF-16 (UCS2):按照双字节存储字符,因此有字节序问题:即高位在前(Big Endian)还是低位在前(Little Endian)。这个行为与CPU处理字节方式有关,一般Little Endian用得比较多。比如“汉”字,Unicode码为0x6C49,按照Big Endian存储就是6C49,Little Endian则为496C。
如何区分不同编码的文件:
用UltraEdit或者类似编辑器打开文本文件,切换到Hex Mode(ctrl + h),看文件头:
- 没有任何特殊文件头的,直接第一个字符就是文本内容的,是ansi文件
- 以BOM (Byte Order Mark) 开头的是否Unicode文件。BOM可以是0xFEFF(表示Big Endian)、0XFFFE(表示Little Endian)、或者0xEFBBBF (UTF-8)。注意,在Windows上用Notepad保存一个UTF-8的文件,也是以0xFFFE开头的。
Unicode与SQL Server:
================
UTF-8是目前使用最广泛的Unicode编码格式,但是SQL Server使用的是UTF-16作为Unicode字符的编码格式,即NCHAR/NTEXT/NVARHCAR存储的都是双字节编码的Unicode字符,以N为前缀(比如N'Hello')的字符串即为双字节Unicode字符。对于UTF-8字符串,如果它只包含ANSI字符,则可以按照ANSI串处理;否则的话必须将UTF-8串转换成UTF-16、再交给SQL
Server 处理。这种行为可能带来两个常见的问题:
- 许多程序(包括ASP.NET)在输出文件的时候都使用UTF-8格式。如果这些文件需要被SQL Server正确地处理,必须进行转码至UTF-16。
- SQL 2005以后支持对Native XML进行处理,但是如果XML文档本身是UTF-8编码,就没办法直接处理。下面是一个例子:
在SSMS中运行如下代码,会得到错误9420:
DECLARE @Inf XML
SET @Inf = '<?xml version="1.0" encoding="utf-8"?>
<root>
<names>
<name>高</name>
</names>
<names>
<name>帅</name>
</names>
</root>
'
SELECT x.value('name[1]', 'VARCHAR(10)') AS Name
FROM @Inf.nodes('/root/names') AS t(x)
即使在给@Inf 赋值时强制指定N前缀转换成Unicode也不行,因为XML文档本身指定了UTF-8编码,解决的方法只有在XML文档中指定UTF-16编码并且指定N前缀:
DECLARE @Inf XML
SET @Inf = N'<?xml version="1.0" encoding="utf-16"?>
<root>
<names>
<name>高</name>
</names>
<names>
<name>帅</name>
</names>
</root>
'
SELECT x.value('name[1]', 'VARCHAR(10)') AS Name
FROM @Inf.nodes('/root/names') AS t(x)
关于看不见的字符0x1D
====================
这个字符为GROUP SEPARATOR,作用是分组,怎么用这个控制字符取决于应用程序。在MS SQL和SSIS中,这个字符并没有特别含义;但是Netezza确实把这个字符当作分隔符使用,导致在数据导入时分栏错误。遗憾的是Netezza的EXTERNAL TABLE导入时没办法控制batch size,所以排查这种问题比较麻烦。对于控制字符,可以在引用EXTERNAL DataSource的时候加上CTRLCHARS
TRUE选项,则可以将控制字符作为字段内容录入。
相关文章推荐
- oracle存储过程转义字符单引号
- leetcode 70Climbing Stairs
- ionic中input框禁止输入问题
- STL源码剖析 [算法](一)[stl_numeric.h]==>copy
- 使用keepalived实现双机热备
- Elasticsearch 免费认证插件Search-guard的部署安装及策略配置
- 贝叶斯定理
- Struts2构建HelloWorld
- qml学习-----------定时器的使用
- 建表语句导致空间浪费的解释
- Android ColorMatrix研究介绍
- UVa 10986 - Sending email
- 腾讯力作!超赞的IOS 8人机界面指南(1):UI设计基础
- 日记20150914
- ionic实现双击返回键退出软件
- NES模拟器开发-CPU笔记
- JS-实现图片横向滑动效果
- Python开发入门与实战20-微信开发配置
- sqlite 操作(使用FMDB)
- 安卓用户小心!新木马病毒可读取并收发短信