在循环中读取用户的输入

时间:2014-10-18 17:54:34

标签: c

我正在使用fgets()。但是,似乎在前一个循环中当前循环中存在剩余部分。但是我在循环中声明input,所以在每个循环中都不是一个新数组吗?

  int nn=0;
  while (1) {
    printf("%d\n", nn);
    if(++nn==3)break;
    char input[101];
    char* pch;
    printf("|%s|\n", input);
    fgets(input, 101, stdin);
    input[strlen(input) - 1] = '\0';
    printf("|%s|\n", input);
    pch = strtok (input," ");

    if(!strcmp(pch, "l")) {
      pch = strtok (NULL, " ");
      readFile(pch, rec, N, buckets, towns);
    }
    else if(!strcmp(pch, "e")) {
      printf("Exiting...\n");
      return;
    }
    else {
      printf("Unknown command. Exiting...\n");
      return;
    }
  }

输出:

0
||
l t200.bin
|l t200.bin|
Records found in file 200 
1
|l|
l t200.bin
|l t200.bin|
Records found in file 200 
2

我担心服务的新命令会与之前的命令纠缠在一起,特别是如果遗留物保留在input中。

2 个答案:

答案 0 :(得分:1)

  

但是,从前一个循环开始,当前循环似乎有剩余部分。但是我在循环中声明了输入,所以不是每个循环都有一个新数组吗?

每次在循环中输入范围时,对于每次迭代,都有一个包含未定义内容的数组。这就是函数中声明的局部数组的工作原理。所以你的第一次循环可以(理论上)input包含任何东西。在你的情况下,发生是一个有效的空字符串......但这不是必需的。后续迭代发生以获得以前的内容......但同样不是必需的,它可以包含任何内容。

请注意,如果在C中将数组声明为 global ,则元素将设置为默认值:

Why are global and static variables initialized to their default values?

虽然你实际上“在每个循环”中获得一个'新的'(未初始化的)数组,但重要的是要意识到你也“在每个循环中丢失旧数组” 。虽然在这种情况下,数组可能会在每次迭代时获得相同的内存地址,但这并不能保证。您无法将数组的地址保存在循环外部声明的指针中,并确保在后续迭代中它将是相同的。

答案 1 :(得分:-1)

您有两个

实例
printf("|%s|\n", input);

一个在你读入输入之前和一个之后;只需删除第一个,在设置之前访问input,导致未定义的行为。

  

不是每个循环都有一个新数组吗?

仅在概念上;实际上,在大多数实现中,它是相同的内存(在堆栈上分配)。这就是为什么你看到前一次迭代的结果。在第一次迭代中,您正在打印堆栈上发生的任何垃圾(可能是NUL)。通过在每次迭代中真正分配新数组的实现,您将在每次迭代时打印垃圾......或者您的程序可能崩溃;再次,它是未定义的行为。

另外,你应该检查fgets是否返回NULL - 表示EOF或错误 - 并且如果是这样则终止你的循环,而不仅仅是你读了'e'。在fgets返回NULL之后{{​​1}}的内容是不确定的。