C - scanf已经变成了ROGUE

时间:2014-12-18 06:20:22

标签: c scanf

我有这个c程序,我输入一个数字N后跟N个更多的数字。例如,我将输入100,然后再输入100个数字。出于某种原因,在这么多输入之后,scanf功能将停止正常工作。就好像它已停止接受输入一样,只会继续使用size中的任何值。

我想出的用例是100 1 2 3 4 5 6 7 8 9 10 ...(重复十次)。然后在三次或四次之后我输入100 10 9 8 7 6 5 4 3 2 1 ...(重复十次)然后会有无限循环的打印声明。

int main(int argc, const char * argv[]) {
  int histogram[10000];
  int i;
  while (1) {
    int *rectPtr = histogram;
    int size;
    scanf("%d", &size);
    if (!size) return 0;
    for (i = 0; i < size; ++i) {
        scanf("%d", rectPtr);
        rectPtr++;
    }
    printf("%d", 1);
    printf("\n");
  }
  return 0;
}

3 个答案:

答案 0 :(得分:1)

IMO,您需要检查scanf()的返回值才能正常运行。请检查以下代码。我添加了一些修改。

要退出程序,您需要按 CTRL + D ,这将生成EOF。或者,在输入一些无效输入时[如char而不是int],也会导致程序从while() llop中跳出并终止。

我已将序列首先检查scanf()。所有其他人也需要检查。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, const char * argv[]) {
        int histogram[10000] = {0};
        int i;

        int *rectPtr = histogram;
        int size = 0;
        int retval = 0;


        printf("Enter the number of elements \n");
        while (  (retval = scanf("%d", &size)) != EOF && (retval == 1)) {
                rectPtr = histogram;
                if (!size) return 0;
                printf("Enter %d elements\n", size);
                for (i = 0; i < size; ++i) {
                        scanf("%d", rectPtr);   //check in a simmilar way to above
                        rectPtr++;
                }
                printf("%d\n", 1111111);

                printf("Enter the number of elements: \n");
        }
        return 0;
}

示例运行的输出

[sourav@broadsword temp]$ ./a.out 
Enter the number of elements: 2
Enter 2 elements
1
2
1111111
Enter the number of elements: 3
Enter 3 elements
1
2
3
1111111
Enter the number of elements: 9
Enter 9 elements
0
9
8
7
6
5
4
3
2
1111111
Enter the number of elements: r   
[sourav@broadsword temp]$

答案 1 :(得分:1)

不信任无限循环。

在一系列评论中,我说:

  

您没有测试scanf()的返回值,因此您不知道它是否正常工作。这对printf()语句很奇怪;为什么不写printf("%d\n", 1);甚至puts("1");

     

您的代码不会测试或捕获scanf()的返回值,因此您不知道scanf()是否报告了问题。作为一般规则,测试输入函数的返回值以确保您认为发生的事实确实发生了。您也可以在阅读之后打印出读取的值:

if (scanf("%d", rectPtr) != 1)
{
    fprintf(stderr, "scanf() failed\n");
    return 1;
}
printf("--> %d\n", *rectPtr);
rectPtr++;
     

同样在输入尺寸时。另请考虑if (size <= 0) return 0;。使用fgets()加上`sscanf()可以使报告错误更容易。

j.will评论道:

  

很高兴知道scanf是否失败,但我想知道它失败的原因并防止它失败。我该怎么做?

我回答:

  

我理解你想知道。使用scanf(),失败后你可以做的最好的事情就是阅读跟随换行符或EOF的所有字符,如果你想知道出了什么问题,那么你也打印这些字符,因为{ {1}}将它在输入缓冲区中读取的最后一个字符留作准备好进行下一个输入操作。

scanf()
     

输出中的第一个字符是导致失败的原因。

     

另见How to use sscanf() in loops?


黑客攻击你的代码:

void gobble(void)
{
    printf("Error at: <<");
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        putchar(c);
    puts(">>");
    if (c == EOF)
        puts("<<EOF>>");
}

答案 2 :(得分:0)

声明

histogram的大小为10000.你说你{em重复10次重复100 1 2 3 ... 。如果我正确理解在histogram中使用了1000个广告位。

如果重复测试超过10次,则会耗尽直方图并开始写入数组末尾,导致未定义的行为。

所以你必须:

  • 在每次迭代时重置recPtr = histogram
  • 阅读尺寸后,
  • 控制recPtr - histogram + size <= sizeof(histogram)(恕我直言更好)

正如其他人所说,你应该总是控制输入操作:任何事情都可能发生在程序之外......