Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么scanf()会在代码中导致无限循环?_C_Gcc_Scanf - Fatal编程技术网

为什么scanf()会在代码中导致无限循环?

为什么scanf()会在代码中导致无限循环?,c,gcc,scanf,C,Gcc,Scanf,我有一个小C程序,它只从标准输入中读取数字,每个循环一个。如果用户输入了一些NaN,则应将错误打印到控制台,并再次返回输入提示。输入“0”时,循环应结束,给定的正/负数值应打印到控制台。节目如下: #include <stdio.h> int main() { int number, p = 0, n = 0; while (1) { printf("-> "); if (scanf("%d", &number) ==

我有一个小C程序,它只从标准输入中读取数字,每个循环一个。如果用户输入了一些NaN,则应将错误打印到控制台,并再次返回输入提示。输入“0”时,循环应结束,给定的正/负数值应打印到控制台。节目如下:

#include <stdio.h>

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

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

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

    printf("Read %d positive and %d negative numbers\n", p, n);
    return 0;
}
#包括
int main()
{
整数,p=0,n=0;
而(1){
printf(“->”);
如果(scanf(“%d”,&number)==0){
printf(“Err…\n”);
继续;
}
如果(数字>0)p++;
如果(数字<0)n++;
else中断;/*0给定*/
}
printf(“读取%d个正数和%d个负数\n”,p,n);
返回0;
}
我的问题是,在输入一些非数字(如“a”)时,会导致一个无限循环反复写入“->Err…”。我想这是一个scanf()问题,我知道这个函数可以被一个更安全的函数代替,但这个例子是给初学者的,他们只知道printf/scanf、if-else和循环

我已经阅读了其他问题的答案并略读了其他问题,但没有什么真正回答这个特定问题。

scanf()
将“
a
”保留在输入缓冲区中,以备下次使用。您可能应该使用
getline()
来读取一行内容,然后使用
strtol()
或类似的方法来解析它


(是的,
getline()
是特定于GNU的,而不是POSIX。那又怎样?问题被标记为“gcc”和“linux”。
getline()
也是读取一行文本的唯一明智选择,除非您想手动完成。)

我认为您只需在继续循环之前刷新缓冲区即可。类似的东西可能会起作用,尽管我无法测试我在这里写的东西:

int c;
while((c = getchar()) != '\n' && c != EOF);

扫描前刷新输入缓冲区:

while(getchar() != EOF) continue;
if (scanf("%d", &number) == 0) {
    ...
我本打算建议使用
fflush(stdin)
,但显然这会导致错误

作为对您的评论的响应,如果您希望显示提示,则必须刷新输出缓冲区。默认情况下,只有在打印换行符时才会发生这种情况。比如:

while (1) {
    printf("-> ");
    fflush(stdout);
    while(getchar() != EOF) continue;
    if (scanf("%d", &number) == 0) {
    ...

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

char c = '0';
if (scanf("%d", &number) == 0) {
  printf("Err. . .\n");
  do {
    c = getchar();
  }
  while (!isdigit(c));
  ungetc(c, stdin);
  //consume non-numeric chars from buffer
}
编辑:修复了一次性删除所有非数字字符的代码。不再为每个非数字字符打印多个“错误”


是SncF.

< P>的一个很好的概述,由于其他代码所指出的<代码> SCANF的问题,您应该真正考虑使用另一种方法。我总是发现
scanf
对于任何认真的输入读取和处理来说都太有限了。使用
fgets
读取整行代码,然后使用
strtok
strtol
等函数处理这些代码(顺便说一句,它们将正确解析整数并告诉您无效字符的确切起始位置)。

而不是使用
scanf()
并且必须处理具有无效字符的缓冲区,请使用
fgets()
sscanf()


我也有类似的问题。我只用scanf解决了这个问题

输入“abc123”
查看其工作原理

#include <stdio.h>
int n, num_ok;
char c;
main() {
    while (1) {
        printf("Input Number: ");
        num_ok = scanf("%d", &n);
        if (num_ok != 1) {
            scanf("%c", &c);
            printf("That wasn't a number: %c\n", c);
        } else {
            printf("The number is: %d\n", n);
        }
    }
}
#包括
int n,num_ok;
字符c;
main(){
而(1){
printf(“输入编号:”);
num_ok=scanf(“%d”&n);
如果(num_ok!=1){
scanf(“%c”、&c);
printf(“那不是一个数字:%c\n”,c);
}否则{
printf(“编号为:%d\n”,n);
}
}
}
在某些平台(特别是Windows和Linux)上,您可以使用
fflush(stdin)

#包括
内部主(空)
{
整数,p=0,n=0;
而(1){
printf(“->”);
如果(scanf(“%d”,&number)==0){
fflush(stdin);
printf(“Err…\n”);
继续;
}
fflush(stdin);
如果(数字>0)p++;
如果(数字<0)n++;
else中断;/*0给定*/
}
printf(“读取%d个正数和%d个负数\n”,p,n);
返回0;
}
我也有同样的想法,我找到了一个有点老套的解决方案。我使用
fgets()
读取输入,然后将其馈送到
sscanf()
。对于无限循环问题,这是一个不错的解决方案,通过一个简单的for循环,我告诉C搜索任何非数字字符。下面的代码不允许像
123abc
这样的输入

#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main(int argc, const char * argv[]) {

    char line[10];
    int loop, arrayLength, number, nan;
    arrayLength = sizeof(line) / sizeof(char);
    do {
        nan = 0;
        printf("Please enter a number:\n");
        fgets(line, arrayLength, stdin);
        for(loop = 0; loop < arrayLength; loop++) { // search for any none numeric charcter inisde the line array
            if(line[loop] == '\n') { // stop the search if there is a carrage return
                break;
            }
            if((line[0] == '-' || line[0] == '+') && loop == 0) { // Exculude the sign charcters infront of numbers so the program can accept both negative and positive numbers
                continue;
            }
            if(!isdigit(line[loop])) { // if there is a none numeric character then add one to nan and break the loop
                nan++;
                break;
            }
        }
    } while(nan || strlen(line) == 1); // check if there is any NaN or the user has just hit enter
    sscanf(line, "%d", &number);
    printf("You enterd number %d\n", number);
    return 0;
}
#包括
#包括
#包括
int main(int argc,const char*argv[]{
字符行[10];
int循环,数组长度,数字,nan;
arrayLength=sizeof(行)/sizeof(字符);
做{
nan=0;
printf(“请输入一个数字:\n”);
fgets(线、排列长度、标准尺寸);
对于(loop=0;loop
嗨,我知道这是一条老线索,但我刚刚完成一项学校作业,在那里遇到了
#include <stdio.h>

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

  while (1) {
    printf("-> ");
    if (scanf("%d", &number) == 0) {
        fflush(stdin);
        printf("Err...\n");
        continue;
    }
    fflush(stdin);
    if (number > 0) p++;
    else if (number < 0) n++;
    else break; /* 0 given */
  }

  printf("Read %d positive and %d negative numbers\n", p, n);
  return 0;
}
#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main(int argc, const char * argv[]) {

    char line[10];
    int loop, arrayLength, number, nan;
    arrayLength = sizeof(line) / sizeof(char);
    do {
        nan = 0;
        printf("Please enter a number:\n");
        fgets(line, arrayLength, stdin);
        for(loop = 0; loop < arrayLength; loop++) { // search for any none numeric charcter inisde the line array
            if(line[loop] == '\n') { // stop the search if there is a carrage return
                break;
            }
            if((line[0] == '-' || line[0] == '+') && loop == 0) { // Exculude the sign charcters infront of numbers so the program can accept both negative and positive numbers
                continue;
            }
            if(!isdigit(line[loop])) { // if there is a none numeric character then add one to nan and break the loop
                nan++;
                break;
            }
        }
    } while(nan || strlen(line) == 1); // check if there is any NaN or the user has just hit enter
    sscanf(line, "%d", &number);
    printf("You enterd number %d\n", number);
    return 0;
}
#include <stdio.h>

    int main()
    {
        int number, p = 0, n = 0;
        char unwantedCharacters[40];  //created array to catch unwanted input
        unwantedCharacters[0] = 0;    //initialzed first byte of array to zero

        while (1)
        {
            printf("-> ");
            scanf("%d", &number);
            gets(unwantedCharacters);        //collect what scanf() wouldn't from the input stream
            if (unwantedCharacters[0] == 0)  //if unwantedCharacters array is empty (the user's input is valid)
            {
                if (number > 0) p++;
                else if (number < 0) n++;
                else break; /* 0 given */
            }
            else
                printf("Err...\n");
        }
        printf("Read %d positive and %d negative numbers\n", p, n);
        return 0;
    }
if (scanf("%d", &number) == 0) {
        printf("Err...\n");
        break;
    }
#include <stdio.h>
int n;
char c[5];
main() {
    while (1) {
        printf("Input Number: ");
        if (scanf("%d", &n)==0) {  //if you type char scanf gets null value
            scanf("%s", &c);      //the abovementioned char stored in 'c'
            printf("That wasn't a number: %s\n", c);
        }
        else printf("The number is: %d\n", n);
    }
}
#include <stdio.h>
#include <ctype.h>

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

    while (1)
    {
        char c;
        int number;
        int success;

        printf("-> ");

        success = scanf("%d%c", &number, &c);

        if ( success != EOF )
        {
            success = success == 2 && isspace( ( unsigned char )c );
        }

        if ( ( success == EOF ) || ( success && number == 0 ) ) break;

        if ( !success )
        {
            scanf("%*[^ \t\n]");
            clearerr(stdin);
        }
        else if ( number > 0 )
        {
            ++p;
        }
        else if ( number < n )
        {
            ++n;
        }
    }

    printf( "\nRead %d positive and %d negative numbers\n", p, n );

    return 0;
}
-> 1
-> -1
-> 2
-> -2
-> 0a
-> -0a
-> a0
-> -a0
-> 3
-> -3
-> 0

Read 3 positive and 3 negative numbers
fgetc(stdin); /* to delete '\n' character */
#include <stdio.h>

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

    while (1) {
        printf("-> ");
        if (scanf("%d", &number) == 0) {
            fgetc(stdin); /* to delete '\n' character */
            printf("Err...\n");
            continue;
        }

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

    printf("Read %d positive and %d negative numbers\n", p, n);
    return 0;
}
int c;
while ((c = fgetc(stdin)) != '\n' && c != EOF);
#include <stdio.h>

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

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

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

    printf("Read %d positive and %d negative numbers\n", p, n);
    return 0;
}
// all you need is to clear the buffer!

#include <stdio.h>

int main()
{
    int number, p = 0, n = 0;
    char clearBuf[256]; //JG:
    while (1) {
        printf("-> ");
        if (scanf("%d", &number) == 0) {
            fgets(stdin, 256, clearBuf); //JG:
            printf("Err...\n");
            continue;
        }

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

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