为什么 scanf() 在此代码中导致无限循环? [英] Why is scanf() causing infinite loop in this code?

查看:29
本文介绍了为什么 scanf() 在此代码中导致无限循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小型 C 程序,它只从标准输入读取数字,每个循环周期一个.如果用户输入了一些 NaN,则应将错误打印到控制台并再次返回输入提示.在输入0"时,循环应该结束,给定的正/负值的数量应该打印到控制台.这是程序:

I've a small C-program which just reads numbers from stdin, one at each loop cycle. If the user inputs some NaN, an error should be printed to the console and the input prompt should return again. On input of "0", the loop should end and the number of given positive/negative values should be printed to the console. Here's the program:

#include <stdio.h>

int main()
{
    int number, p = 0, n = 0;

    while (1) {
        printf("-> ");
        if (scanf("%d", &number) == 0) {
            printf("Err...
");
            continue;
        }

        if (number > 0) p++;
        else if (number < 0) n++;
        else break; /* 0 given */
    }

    printf("Read %d positive and %d negative numbers
", p, n);
    return 0;
}

我的问题是,在输入一些非数字(如a")时,这会导致无限循环一遍又一遍地写入-> Err...".我想这是一个 scanf() 问题,我知道这个函数可以用更安全的函数代替,但这个例子是为初学者准备的,只知道 printf/scanf、if-else 和循环.

My problem is, that on entering some non-number (like "a"), this results in an infinite loop writing "-> Err..." over and over. I guess it's a scanf() issue and I know this function could be replace by a safer one, but this example is for beginners, knowing just about printf/scanf, if-else and loops.

我已经阅读了这个问题的答案 并浏览了其他问题,但没有真正回答这个具体问题.

I've already read the answers to this question and skimmed through other questions, but nothing really answer this specific problem.

推荐答案

scanf 只消费匹配格式字符串的输入,返回消费的字符数.任何与格式字符串不匹配的字符都会导致它停止扫描并将无效字符留在缓冲区中.正如其他人所说,您仍然需要在继续之前将无效字符从缓冲区中清除.这是一个相当肮脏的修复,但它会从输出中删除有问题的字符.

scanf consumes only the input that matches the format string, returning the number of characters consumed. Any character that doesn't match the format string causes it to stop scanning and leaves the invalid character still in the buffer. As others said, you still need to flush the invalid character out of the buffer before you proceed. This is a pretty dirty fix, but it will remove the offending characters from the output.

char c = '0';
if (scanf("%d", &number) == 0) {
  printf("Err. . .
");
  do {
    c = getchar();
  }
  while (!isdigit(c));
  ungetc(c, stdin);
  //consume non-numeric chars from buffer
}

修复了一次性删除所有非数字字符的代码.不再为每个非数字字符打印多个Errs".

edit: fixed the code to remove all non-numeric chars in one go. Won't print out multiple "Errs" for each non-numeric char anymore.

这里是一个很好的概述扫描.

Here is a pretty good overview of scanf.

这篇关于为什么 scanf() 在此代码中导致无限循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆