在 while 循环内使用 scanf 读取数组时出现意外行为

问题描述 投票:0回答:2

我编写了一个程序来将数字读取到整数数组 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; 
}
c arrays while-loop scanf
2个回答
2
投票

我能想到的问题:

  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++;;
    }
    

1
投票

每当使用

scanf()
系列函数时,请务必检查返回值。 @用户694733

使用

scanf("%d",&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()

© www.soinside.com 2019 - 2024. All rights reserved.