【问题标题】:Infinite loop when getting a line with getchar()使用 getchar() 获取一行时的无限循环
【发布时间】:2013-09-05 06:54:20
【问题描述】:

我正在尝试 K&R(例如 1-17)的练习,我想出了自己的解决方案。 问题是我的程序似乎挂起,可能处于无限循环中。我省略了 NUL ('\0') 字符插入,因为我发现 C 通常会自动将它附加到字符串的末尾(不是吗?)。

有人可以帮我找出问题所在吗?

我在 win8(x64) 上使用带有 Cygwin 的 GCC 编译器,如果有帮助的话..

问题 - 打印所有超过 80 个字符的输入行

#include<stdio.h>

#define MINLEN 80
#define MAXLEN 1000

/* getlin : inputs the string and returns its length */
int getlin(char line[])
{
    int c,index;

    for(index = 0 ; (c != '\n') && ((c = getchar()) != EOF) && (index < MAXLEN) ; index++)
        line[index] = c;

    return (index);                                                                     // Returns length of the input string
}

main()
{
    int len;
    char chArr[MAXLEN];

    while((len = getlin(chArr))>0)
    {
        /* A printf here,(which I had originally inserted for debugging purposes) Miraculously solves the problem!!*/
        if(len>=MINLEN)
            printf("\n%s",chArr);
    }
    return 0;
}

【问题讨论】:

  • “我发现 C 通常会自动将它附加到字符串的末尾” 你在哪里找到的?
  • 关于代码中的问题:在getlin 中,第一次测试c != '\n' 时,c 未初始化,并且将具有不可预测的值,很可能正是'\n'。声明时初始化它(在声明变量时总是这样做是一个好主意,以避免这样的错误)。
  • 非常感谢您,好心的先生 -- 这完全解决了问题..

标签: c kernighan-and-ritchie


【解决方案1】:

我省略了 null('\0') 字符插入,因为我发现 C 通常会自动将它附加到字符串的末尾(不是吗?)。

不,它没有。您正在使用 getchar() 一次读取一个输入字符。如果您自己将字符放入数组中,则必须自己终止它。

返回字符串的 C 函数通常会终止它,但这不是您在这里所做的。

您的输入循环有点奇怪。逻辑 AND 运算符仅在左侧计算结果为 false 时执行右侧(称为“短路”)。重新排列循环中测试的顺序应该会有所帮助。

for(index = 0 ; (index < MAXLEN) && ((c = getchar()) != EOF) && (c != '\n'); index++)
    line[index] = c;

这样,cgetchar() 接收一个值您对其内容执行测试之前。

【讨论】:

  • 非常感谢您的回答。但是,在数组末尾没有 \0 的情况下,程序运行良好。当我输入少于 80 个字符的句子时,程序挂起.. 即使在字符串末尾添加一个 null 也无济于事.. 有什么想法吗,先生?
  • @Somu 我已经编辑,对循环条件提出建议。
  • 再次感谢.. 成功了.. 非常感谢.. 好像我做错了很多事情..
  • 不客气。如果这解决了问题,您可以单击复选标记以接受答案。 :)
【解决方案2】:

我不肯定出了什么问题,但你没有向程序提供输入,所以我猜。

我的猜测是,在 getlin 中,您的变量 c 被设置为 '\n' 并且此时它永远不会获得另一个字符。它只是不断返回和循环。

在测试之前,你从来没有对 getlin 函数中的任何内容设置 c,这是问题所在。

【讨论】:

    【解决方案3】:

    C 不会自动在字符串末尾插入 NUL 终止符。某些函数可能会这样做(例如 snprintf)。请查阅您的文档。此外,请注意初始化所有变量,例如 getlin() 中的 c

    【讨论】:

      【解决方案4】:

      1) C 不会在您的字符串中添加最终的\0。您负责使用至少包含 81 个字符的数组,并将最后的 \0 放在您写入的最后一个字符之后。

      2) 在阅读之前您正在测试c 的值

      3) 您的程序不会打印任何内容,因为 printf 使用 I/O 缓冲区,当您发送 \n 时该缓冲区会被刷新。修改此语句以打印最终的\n

      printf("\n%s",chArr);
      

      变成:

      printf("%s\n",chArr);
      

      4) 要将 EOF 发送到您的程序,您应该在 unix 下执行 Ctrl+D,我不知道 Windows 是否可以。这可能是节目永远不会结束的原因。

      【讨论】:

        猜你喜欢
        • 2018-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-09
        • 1970-01-01
        相关资源
        最近更新 更多