【问题标题】:Unexpected behaviour when scanf used inside while loop to read an array在 while 循环中使用 scanf 读取数组时出现意外行为
【发布时间】:2014-12-11 07:52:14
【问题描述】:

我编写了一个程序来将数字读入整数数组 a[100]。当用户输入字符'e'或数组达到最大大小时,读取停止。

但是当代码运行时,我得到了一个意想不到的行为,当用户输入“e”时,将数字扫描到数组中会按照我在程序中的意图终止,但是 while 循环中的其余语句包括增量变量 (i++)和 printf 函数我用来调试代码,直到 while 的条件部分中的第一个条件变为 false。

#include <stdio.h>

int main(){
int a[100];
puts("Enter numbers(enter \"e\" to stop entring)\n");
int i=0;
scanf("%d",&a[i]);
while(i<100&&a[i]!='e'){
     i++;;
     scanf("%d",&a[i]);
     printf("\n -----> %d\n",i);
}
printf("\n\t i ---> %d\t\n",i);
return 0; 
}

【问题讨论】:

  • a[i]!='e'???我以为你想扫描整数。是的,'e' 扩展为int,但如果这确实是您想要实现的目标,那么您为什么不使用char 数组,为什么不扫描'%c'
  • 检查scanf的返回值,答案应该很明显了。
  • while(i&lt;100 &amp;&amp; a[i] !='e' 正在与未初始化的数组进行比较。

标签: c arrays while-loop scanf


【解决方案1】:

我能想到的问题:

  1. 数组索引的增量需要更新。

    while(i<100&&a[i]!='e'){
         // When i 99 before this statement, i becomes 100 after the increment
         i++;;
         // Now you are accessing a[100], which is out of bounds.
        scanf("%d",&a[i]);
        printf("\n -----> %d\n",i);
    }
    

    你需要的是:

    while(i<100&&a[i]!='e'){
        scanf("%d",&a[i]);
        printf("\n -----> %d\n",i);
        i++;;
    }
    
  2. 如果您的输入流包含e,则声明

    scanf("%d",&a[i]);
    

    不会向a[i] 阅读任何内容。

    您可以通过以下方式解决此问题:

    1. 将输入作为字符串读取。
    2. 检查字符串是否为e。如果是这样,请跳出循环。
    3. 如果没有,请尝试从字符串中获取数字。

    这是一个更新的版本:

    char token[100]; // Make it large enough 
    while(i<100) {
        scanf("%s", token);
        if ( token[0] == 'e' ) // Add code to skip white spaces if you 
                               // want to if that's a possibility.
        {
           break;
        }
        sscanf(token, "%d", &a[i]);
        printf("\n -----> %d\n",i);
        i++;;
    }
    

【讨论】:

    【解决方案2】:

    每当使用scanf() 系列函数时,一定要检查返回值。 (@user694733)

    使用scanf("%d",&amp;a[i]); 读取“e”失败,scanf() 返回 0,表示未发生转换。 "e" 保留在 stdin 中,直到它可以被正确读取,OP 的代码永远不会阻止后续输入。

    将用户输入读取为字符串,测试是否为“e”,否则转换为int

    int main(void) {
      int a[100];
      puts("Enter numbers(enter \"e\" to stop entering)\n");
      int i = 0;
      for (;;) {
        char buf[50];
        if (fgets(buf, sizeof buf, stdin) == NULL) {
          break;  // Input was closed
        }
        if (strcmp(buf, "e\n") == 0) {
          break; // normal method to stop entering.
        }
        if (sscanf(buf, "%d", &a[i]) != 1) {  // or use strtod()
          break; // Some other garbage entered.
        }
        printf("\n -----> %d %d\n", i, a[i]);
        i++;  // increment afterwards @R Sahu
      }
      printf("\n\t i ---> %d\t\n",i);
      return 0; 
    }
    

    注意:建议不要使用scanf()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-04
      • 2018-01-10
      • 2015-11-16
      • 1970-01-01
      • 2013-11-23
      • 1970-01-01
      • 1970-01-01
      • 2018-04-17
      相关资源
      最近更新 更多