记:在自己的实验中,需要把一个数据集(文本文件)转换成另一种格式(文本文件)。转换中,读取一行至结尾,没有理会最后的回车换行符,直接抛弃处理。在
新格式的文本中,写一行后通过fprintf(fp,"A%d: \tcontinuous. |type:
A\n",i);中的\n作为换行。生成格式看上去和要求的一模一样,但在处理程序调用新格式中的数据时,在这个换行处出了问题。getc(fp)到换行
处,得到的是ascii码值为10的LF。根据我的处理程序要求,此处的换行应该能够直接跳过去。那么,到底是文本中换行符出了问题呢,还是我的程序处理
出了问题?其实就是因为在回车换行符的认识上出了问题。
一、回车,换行
在ASCII表中有对应的值。374@[1]
ASCII值
|
字符
|
控制字符
|
010
|
line feed
|
LF
|
013
|
carriage return
|
CR
|
{feed:把纸放进打印机;给装置提供数据资料。流入,喂养}
{carriage:在打印机上在下一页进纸前作准备的机械;打字机的进纸处;马车;运输}
在C语言中,它们有对应的转义字符表示。page48@[1]
字符形式
|
含义 |
ASCII代码
|
\n
|
换行,将当前位置移到下一行开头
|
10
|
\r
|
回车,将当前位置移到本行开头
|
13
|
在文本文件中\n和\r显示的效果有一些不同,在windows的notepad中\r在显示中没有作用,在editplus和notepad++中显示有换行的效果;\n都显示有换行的效果;在linux下的VI下看到的效果是:\r显示为^W,\n没有对应显示字符。看到这里,很多人还是会云里雾里,我也是^_^.引用别人的一篇关于回车和换行区别的文章,相信很多朋友就明白了,详情参考[2],一针见血的文章让我忍不住要留在自己文章的下面:-)
二、在我的程序中,需要的是每一行后面只有换行没有回车。但是在我写好的文件中莫名地出现了回车符。
1 #include
2
3 int main(int argc, char *argv[])
4 {
5 FILE *fp;
6 if((fp=fopen("36TMpssm28.names","w"))==NULL)
7 {
8 printf("cannot open 36TMpssm28.names!");
9 return -1;
10 }
11 fputs("+,-.\n\n",fp);
12 for(int i=1;i<=260;i++)
13 fprintf(fp,"A%d: \tcontinuous. |type: A\n",i); fclose(fp);
14 return 0;
15 }
这段程序写出的36TMpssm28.names中每行的结尾处是\r\n两个字符。为什么呢?
原因是上面为写文件打开的是文本文件方式,存在转换的问题。在向计算机输入文本文件时,将回车换行符转换为一个换行符,在输出时把换行符转换成为回车和换
行两个字符。在用二进制文件时,不进行这种转换,在内存中的数据形式与输出到外部文件中的数据形式完全一致,一一对应。313@[1]
结论: 1、回车和换行可分可合。在文件中合,在内存中分。 2、在文件读写时,文本文件方式有字符转换发生;二进制文件方式完全一一对应,没有字符转换。
[1]谭浩强 C程序设计 第二版 清华大学出版社
[2]http://www.cppblog.com/gtwdaizi/articles/38229.html
ps:
今天,我总算搞清楚“回车”(carriage return)和“换行”(line feed)这两个概念的来历和区别了。
在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。
于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。
这就是“换行”和“回车”的来历,从它们的英语名字上也可以看出一二。
后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。
Unix 系统里,每行结尾只有“<换行>”,即“\n”;Windows系统里面,每行结尾是“<换行><回车>”,即“ \n\r”;Mac系统里,每行结尾是“<回车>”。一个直接后果是,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