![为什么命令提示符和 PowerShell 给出的输出结果与终端不同?](https://linux22.com/image/1605790/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%91%BD%E4%BB%A4%E6%8F%90%E7%A4%BA%E7%AC%A6%E5%92%8C%20PowerShell%20%E7%BB%99%E5%87%BA%E7%9A%84%E8%BE%93%E5%87%BA%E7%BB%93%E6%9E%9C%E4%B8%8E%E7%BB%88%E7%AB%AF%E4%B8%8D%E5%90%8C%EF%BC%9F.png)
我有一本书中的以下示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
printf("Hello World (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0)
{
//fork failed
fprintf(stderr, "fork failed\n");
exit(1);
}
else if (rc == 0)
{
//child (new process)
printf("Hello I am child (pid:%d)\n", (int) getpid());
}
else
{
//parent goes down this path (main)
printf("Hello, I am parent of %d (pid:%d)\n",
rc, (int) getpid());
}
return 0;
}
在 Windows(powershell 和命令提示符)中,我得到以下信息:
Hello World (pid:1283)
Hello, I am parent of 1284 (pid:1283)Hello I am child (pid:1284)
在 Linux (终端) 中我得到:
Hello World (pid:1923)
Hello, I am parent of 1924 (pid:1923)
Hello I am child (pid:1924)
如下图所示。
为什么相同的代码在不同的程序中显示不同?Windows 是否只是根据其读取代码的方式错误地显示输出?还是它的编译器出了问题?我在 Linux 上使用附带的 gcc。我在 Windows 上使用 cygwin gcc。
Windows 上的 PowerShell
Linux 上的终端
Windows 上的命令提示符
同时运行此代码:
#include <stdio.h>
int main()
{
printf("Name\n");
printf("Address Line 1\n");
printf("Address Line 2");
}
在 Windows 上的 PowerShell 中正确打印代码。
答案1
对于 Cygwin 来说,有一个显然是一种竞争条件它输出构成行主体的字符,然后输出行尾(CRLF
),另一个进程能够介入,这样您实际上就得到了body1 body2 CRLF CRLF
(为清楚起见添加了间距)。
标准 C 禁止将标准输出完全缓冲到“交互式设备”(即多于一行),但允许缓冲较少的内容,而且无论如何,操作系统(C 正式称之为“主机环境”)如何处理来自多个进程的输出一旦“传输”给它就完全超出了 C 的范围 — — 如果我没记错的话,在这种情况下甚至超出了 POSIX 的范围 — — 无论如何,Cygwin 都不能完全满足 POSIX。
答案2
您却在 Windows 上使用 Unix 换行符 ( \n
),而它应该是\r\n
。
差异很好这里解释:
有三种不同类型的换行符,它们最初都是各大操作系统所独有的:Windows/DOS、Macintosh 和 Unix。使用 Mac 换行符的文档在 Windows 系统上看起来很糟糕,而使用 Windows 换行符的文档在 Unix 上也无法正确解释。造成这种情况的原因在于换行符的实际创建方式。默认情况下,Mac 使用单个回车符 (
<CR>
),表示为\r
。而 Unix 使用单个换行符 (<LF>
),\n
。Windows 更进一步,同时使用两者,创建 () 组合,\r\n
。
要亲自测试,只需更改以下几行:
printf("Hello World (pid:%d)\n", (int) getpid());
fprintf(stderr, "fork failed\n");
printf("Hello I am child (pid:%d)\n", (int) getpid());
printf("Hello, I am parent of %d (pid:%d)\n",
rc, (int) getpid());
对此:
printf("Hello World (pid:%d)\r\n", (int) getpid());
fprintf(stderr, "fork failed\r\n");
printf("Hello I am child (pid:%d)\r\n", (int) getpid());
printf("Hello, I am parent of %d (pid:%d)\r\n",
rc, (int) getpid());
如果希望换行符在跨平台上保持一致,我建议只需根据 OS/shell 版本在代码中应用一个常量即可,该常量将分配正确的换行符,然后将其分配给\n
代码中的所有位置。