【问题标题】:Why for loop never ends?为什么for循环永远不会结束?
【发布时间】:2020-09-11 05:38:43
【问题描述】:
int ln;
printf("how many letters are your name?\n");
scanf("%d", &ln);
printf("Ok...enter your name by characters: \n");
char name[ln];
for (int i = 0; i<=ln; i++){
    scanf("%s", &name[i]);
}

此代码应转换数组中的名称,但 for 循环永远不会结束。谁能帮帮我?

【问题讨论】:

  • 格式说明符、VLA、...标准库已经具有读取字符串的功能。
  • 注意:%s 用于读取字符串
  • 使用getchar() 来读取字符...或者,如果您必须(但实际上您不应该)...scanf(" %c", ...)

标签: c arrays string for-loop variable-length-array


【解决方案1】:

"为什么 for 循环永远不会结束?"

首先,我不认为循环是无限的。对我来说,您似乎只是将%s%c 混淆了,并将等待更多输入解释为“永不结束”的循环。

不过,您没有提供足够的资源来重建您的问题。

让我们开始吧:

  1. scanf()%s 转换说明符用于读取字符串,而不是单个字符。如果您想每次迭代读取一个字符,请在 for 循环中使用 scanf("%c", &amp;name[i]);name[i] = getchar(); 而不是 scanf("%s", &amp;name[i]);

  2. 您的循环条件i &lt;= ln 有问题,因为您尝试用它多写一个字符,因为索引计数从0 开始,而不是1。请改用i &lt; ln

  3. 字符串的末尾需要有一个终止空字符。 name 需要多一个元素,而不仅仅是保存输入名称的字母。还要在循环之后放置name[ln] = '\0';,以便在VLA name 的最后一个元素中插入一个空字符。


注意:

如果您想从stdin 中读取在运行时确定的可变数量的字符,则无需单独读取每个字符并在计数器到达ln - 1 之前停止。

读取具有可变数量字符的字符串是一点,其中fgets()scanf()更合适。

使用fgets (name, sizeof(name), stdin); 确保读取的字符串加上以字符串结尾的空字符将完全适合name 并捕获名称一次。

int ln;

printf("How many letters are in your name?\n");
scanf("%d", &ln);
getchar();              // catching left newline from scanf.

char name[ln + 1];      // +1 for null character.

printf("Ok...enter your name: \n");

fgets(name, sizeof(name), stdin);   // Will read the name and append the null character.

getchar();              // catching left newline from fgets. 
   

【讨论】:

  • 我已经尝试过这段代码,但是当我运行它时,它会在 2 个字符后停止
  • @Jack_01 嗯... :-/ 我想我需要看看你更正的代码。
  • @Jack_01 Ok...enter your name by characters: 打印出来了吗?
  • int ln; printf("How many letters are in your name?\n"); scanf("%d", &amp;ln); getchar(); char name[ln + 1]; printf("Ok...enter your name by characters: \n"); fgets(name, sizeof(name), stdin); getchar();
  • @Jack_01 好的。你的实际输入是什么?你什么时候按 Enter 键?
【解决方案2】:

%s 正在扫描字符串,因此从技术上讲,您的全名被视为一个元素。所以要输入很多字符串。只需将 %s 替换为 %c,代码就可以使用了

【讨论】:

    【解决方案3】:

    为什么 for 循环永远不会结束?

    在循环内部,scanf("%s", &amp;name[i]); 尝试读取名称 ln + 1 次,最终尝试将数据保存在 name[] 范围之外。

    name[] 范围之外保存数据是未定义的行为 (UB)。任何事情都可能发生。


    循环不需要读取一行输入作为名称,name[] 太小。

    //char name[ln];
    //for (int i = 0; i<=ln; i++){
    //   scanf("%s", &name[i]);
    //}
    
    char name[ln+1];  // One more for a \0
    if (scanf("%s", &name[i]) ==1) {
      Success();
    }
    

    建议不要使用scanf(),而使用fgets()

    char name[ln+1+1]; / One more for a \n and 1 for a \0
    if (fgets(name, sizeof name, stdin)) {
      name[strcspn(name, "\n")] = '\0';  // lop off potential \n
      Success();
    }
    

    【讨论】:

      【解决方案4】:

      因为你的 for 循环必须再运行一次才能结束。简单地改变

      i<=ln
      

      i<ln
      

      【讨论】:

        【解决方案5】:

        在 for 条件中,尝试删除该相等性并查看,因为您在 name 变量中分配 ln 字节,所以变量 i 将从 0 开始并转到 ln-1

        for (int i = 0; i<ln; i++){
               scanf("%c", &name[i]);
           }
        

        还要注意我在这里使用 %c 扫描字符,%s 扫描字符串。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-09-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-20
          • 2011-08-04
          • 2017-05-21
          • 1970-01-01
          相关资源
          最近更新 更多