fgets和处理CTRL+D输入

4

我正在获取用户的标准输入,如果用户按下 CTRL+D,我希望显示一个错误并终止程序。我认为我的问题可能与被困在 while 循环中有关;

int readInput(){
   char buff[10];
   int count = 0;
   int counter;
   printf("Enter random number: ");
   fgets(buff, 10, stdin);
   if ((int) strtol(buff, NULL, 10) == 0){
      printf("Error reading number. \n");
      return 0;   //This will get hit if the user presses CTRL+D at this input.
   }
   counter = atol(buff);
   while (count < counter){ 
      printf("Enter a label: ");
      fgets(buff, 10, stdin);
      if ((int) strtol(buff, NULL, 10) == 0){
         printf("Error reading label");
         return 0;  //This will not get hit if the user presses CTRL+D at this input, but why?
         //I've also tried assigning a variable to 0, breaking out of the loop using break; and returning the variable at the end of the function but that also does not work.

      //the rest of the while loop continues even if user hit CTRL+D
      printf("Enter Value: " );
      fgets(buff, 10, stdin);
      //..rest of while loop just gets other inputs like above
      count++;
   }

//termination happens in main, if readInput returns a 0 we call RETURN EXIT_FAILURE;

我不明白为什么在第一次输入时,如果用户按下CTRL+D,程序会做出相应的反应,但第二次输入时却完全忽略了它。


while循环中计数器的递增方式很奇怪。另外,计数器是否被递增过? - ryyker
这是在Ubuntu机器上,是的。 - Talen Kylon
计数器在最后一行被增加,counter是用户输入的随机整数。我更关注的是为什么我的检查是否按下CTRL+D的代码在while循环中不起作用,但在外部却可以。 - Talen Kylon
1个回答

9
在Linux上,Ctrl + D 会生成 EOF,因此每次都需要检查 fgets() 的返回值。当遇到 EOF 时,fgets() 返回一个空指针。
if (fgets(buff, 10, stdin) == NULL)
    print_error();

明白了,你有什么想法,为什么第一次检查 CTRL+D 能够正常工作? - Talen Kylon
因为D会自动将缓冲区初始化为\0(至少在调试模式下),而在第二个测试中,您仍然保留了buff中的旧值。 - ratchet freak
1
@YuHao 实际上,如果 buff 的第一个位置是任何非数字字符,strtol 将返回 0,因此它在 256 中有 10 的机会无法正常工作。 - ratchet freak
我以为 Ctrl + D 是 EOT 字符? - Horse SMith
@HorseSMith Unix中的意义 - Yu Hao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接