程序以奇怪的顺序执行

时间:2014-12-04 06:40:25

标签: c linux

#include<stdio.h>
#define DEBUG
int main()
{
     #ifdef DEBUG 
     freopen("ddd.txt","a",stdout);
     freopen("ddd.txt","a",stderr);
     #endif
     printf("1\n");
     perror("2");
     printf("3\n");
     perror("4");
     printf("5\n");
     perror("6"); 
 }

正如@JonathanLeffler所说,在Mac OS X 10.10.1上使用GCC 4.9.1,这给出了:

2: Undefined error: 0
4: Undefined error: 0
6: Undefined error: 0
1
3
5

为什么奇怪的命令?

此外,perror返回“无效参数”作为错误。在同一个文件上使用freopen是否安全?

1 个答案:

答案 0 :(得分:2)

我在Mac OS X 10.10.1上使用GCC 4.9.1获得的输出是:

2: Undefined error: 0
4: Undefined error: 0
6: Undefined error: 0
1
3
5

序列就是这样,因为标准错误没有被缓冲,标准输出被缓冲了。

可能有多种原因导致错误EINVAL,无效参数。除非freopen()返回错误指示,否则您无需检查errno中的值;即使成功,库函数也可以设置errno。 (例如,在Solaris上,许多输出操作会将errno设置为ENOTTY,而不是tty,当输出是终端以外的其他内容时,即使操作成功。)

请注意,在使用流之前,应严格检查freopen()的返回值是否为NULL。如果无法创建文件或无法写入文件或者是目录等,则调用可能会失败。

并解决你的问题:

  

在同一个文件上使用freopen是否安全?

这取决于您对'安全'的定义。你的电脑会爆炸吗?不,不仅仅是因为这个原因。 freopen()第二次尝试会失败吗?不,它没有。你能用数据获得有趣的交错效果吗?是的,当然了。标准输出块(不一定以换行符结尾)可以很容易地与标准错误行交错。你经常这样做吗?不,你不会经常这样做。如果这样做,您可能希望在调用freopen()后立即将标准输出和标准错误设置为使用setvbuf()缓冲的行。这样可以减少看似奇怪的输出量。