EOS在MacOS和CentOS上的结果不同

时间:2019-07-07 02:55:32

标签: c macos centos

我正在使用EOF跳出“ while”循环,并希望通过“ scanf”输入一些数字。循环外的“ scanf”不适用于macOS。

我试图在macos和centos上运行此代码。结果是我需要的。

#include <stdio.h>
#include <stdlib.h>
int main(){
 int i;
 //ctrl+d=EOF
 while(scanf("%d",&i) != EOF){
  printf("?");
 }
 printf("\nloopend\n");
 //those 'scanf' are ignored on macos.
 scanf("%d",&i);
 scanf(" %d",&i);
 scanf("%d ",&i);
 printf("\nend\n");
}

输入(不带','): 1,\ n,ctrl + d

输出(centos):

1
?
loopend
//waiting for input here

输出(macos):

1
?
loopend

end
//the program ended directly

1 个答案:

答案 0 :(得分:4)

MacOS行为正确。根据{{​​3}}(fgetc库函数),文件结束指示是粘性的; fgetc一旦看到EOF,就必须设置文件的文件结束指示符,这将导致后续调用返回EOF,直到清除文件结束指示符为止,例如使用{{1 }}:

  

如果设置了流的文件结束指示符,或者流在文件末尾,则设置了流的文件结束指示符,并且fgetc函数返回EOF。否则,fgetc函数从流指向的输入流中返回下一个字符。如果发生读取错误,将设置流的错误指示符,并且fgetc函数将返回EOF。

由于其他输入功能(包括clearerr()的作用似乎是通过重复调用scanf来实现的,因此EOF也应该对它们具有粘性。如果您希望在收到EOF返回单后继续阅读,则应在流中调用fgetc。 (或其他重置指标的内容,例如clearerr()。)

多年来,标准C库的Gnu实现未遵循该标准。它仅报告一次EOF,而使下一个seek()停留在终端和管道等设备上等待更多输入。该错误报告于2006年,是C standard §7.21.7.1/3,于2018年8月发布,尽管该错误可能尚未成为Centos发行版的一部分。

[注意:finally fixed in v2.28中对此行为的讨论时间更长,包括(我本人)现在已经过时的脾气,以及一些有关该问题的历史性讨论的链接。] < / p>

无论如何,由于BSD派生的标准库实现(包括MacOS)遵循上面引用的标准,因此始终清楚可移植代码应调用fgetc