您的位置:首页 > 运维架构 > Linux

Linux和Windows对"\r\n"的不同处理

2013-04-20 20:55 429 查看
有关于'\r'与’\n‘的来源,网上有相关的资料。我在fgets/gets/scanf函数读入字符串比较中也有提到。简而言之,在Linux环境下,换行是"\n";而在Windows下,换行是"\r\n"。在编写程序的时候,通常可以使用freopen函数将程序输入流重定向为文件。于是问题就来了,假如一个文件(test.txt)包含如下字符串:

“ustc\rchina\r\n”

注:其中\r和\n是转义字符,因此上一行共12个字符。

那么,在Linux和Windows环境下,下列程序会有怎样的结果呢?

#include <stdio.h>

int main()
{
freopen("test.txt", "r", stdin);
char ch, str[100];
int i = 0;
while ((ch = getchar()) != EOF)
str[i++] = ch;
str[i] = 0;
return 0;
}
#include <stdio.h>

int main()
{
freopen("test.txt", "r", stdin);
char ch, str[100];
int i = 0;
while ((scanf("%c", &ch)) != EOF)
str[i++] = ch;
str[i] = 0;
return 0;
}
在Windows下运行以上两个程序,可以看到代码运行到第11行时,str[4]的值为13,也就是'\r'的值,而str[10]的值为10,也就是'\n'的值,str[9]的值则是97,是字符a的ASCII码值。

可见,在Windows下,操作系统将“\r\n”处理为一个字符'\n'。

而在Linux下运行以上程序,又会得到怎样的结果呢?str数组存储的,是“ustc\rchina\r\n”,也就是和原文本一模一样的内容。这是因为Linux只认'\n'作为换行。并不像Windows那样将“\r\n“转化为'\n'。【事实上,之所以Windows要对"\r\n"进行转化,是因为你在Windows环境下,printf("\n")输出的,实际上就是”\r\n“】

接下来我们再看gets(str)和scanf("%s", str);的区别。依然假设test.txt文本文件中有如下一行字符:、

“ustc\rchina\r\n”

然后我们分别在Windows和Linux下运行下列程序:

#include <stdio.h>

int main()
{
freopen("test.txt", "r", stdin);
char str[100];
gets(str);
str[0] = 0;
gets(str);
return 0;
}

在Windows下,第一个gets函数执行完之后,str的值为”ustc\rchina“,第二个gets函数没有改变str的值(因为已经读完文件了)。而在Linux下,第一个gets函数执行完之后,str的值为”ustc\rchina\r“。

下面我们在看scanf("%s", str)的表现。

#include <stdio.h>

int main()
{
freopen("test.txt", "r", stdin);
char str[100];
scanf("%s", str);
str[0] = 0;
scanf("%s", str);
return 0;
}
上述代码在Windows下,第一个gets函数执行后,str的值为”ustc“,第二个gets函数执行后,str的值为"china"。在Linux下得到的结果与Windows下相同。【这是因为对于scanf函数而言,'\r'也是空白符,scanf读入字符串的规则是:遇到空白符完成读取】

总之,Windows仅在\r和\n连续出现为'\r\n'才将其转化为‘\n’,其他情况不做处理。所以当'\r'字符单独出现的时候,程序在Linux和‘windows环境下无差异。即,在Windows下,”\r\n“被视为一个字符('\n');而Linux下,”\r\n“依然是两个字符。

PS:如何生成包含"ustc\rchina\r\n"内容的文本。

在Windows下,代码如下:

#include <stdio.h>
int main()
{
freopen("test.txt", "w", stdout);
printf("ustc\rchina\n");
return 0;
}而在Linux下,则需编写为:
#include <stdio.h>
int main()
{
freopen("test.txt", "w", stdout);
printf("ustc\rchina\r\n");
return 0;
}
这是因为printf函数中的“\n”的一个逻辑换行,而这个逻辑换行在Windows下就是‘\r\n’(LF CR)两个字符;而在Linux下,逻辑换行也就是'\n'(即CR)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  CC++