在C中的无限循环中使用getchar()

时间:2017-08-29 05:56:03

标签: c while-loop infinite-loop getchar

我想输入一个字符并获得相应的ASCII整数作为输出。我使用getchar()来获取输入,使用while创建一个无限循环,当q' q'进入。我的代码是 -

#include <stdio.h>

int main() {
    int c;

    printf("Enter a character(press q to exit):\n");

    while(1) {
        c = getchar();
        printf("%d\n",c);

        if(c == 'q')
            break;
    }

    printf("End of the program");
    return 0;
}

当输入q退出程序时,程序运行正常。但是,如果我输入任何其他字符,则数值最后会添加10。例如,如果我输入i,则输出为

Enter a character(press q to exit): 
i 
105
10
I
73
10

任何角色都在最后添加了10个角色。我做错了什么?

3 个答案:

答案 0 :(得分:2)

10是ASCII换行符,由于你在每一行的末尾按 ENTER ,它被放置在缓冲区中。

如果你想忽略这些字符,就不要对它们采取行动:

#include <stdio.h>
int main (void) {
    int c;
    printf ("Enter a series of characters (q will exit): ");
    for (;;) {
        c = getchar();
        if ((c == 'q') || (c == EOF)) // stop if EOF or 'q'.
            break;
        if (c != '\n')                // only print non-newlines.
            printf ("%d\n", c);
    }
    printf ("End of the program");
    return 0;
}

请注意,我也在检查循环中的文件结尾,否则返回值将导致一个相当恼人的无限循环。

答案 1 :(得分:2)

使用getchar()时作为C程序员的主要工作是考虑输入缓冲区中的所有字符。当您输入a并按返回时,getchar();会读取'a',但会按返回生成'\n'输入缓冲区 stdin中。在下一次循环中,代码似乎绕过任何提示而不等待输入 - 为什么? ,因为{{1}已有一个字符只是等待阅读 - getchar()

因此,任何这些面向字符的输入问题,都必须在<{1}}中留下会计帽子并对其中的每个字符进行说明。有几种方法可以做到这一点。 Paxdiablo展示了一种非常好的方法。另一种类似的方法是使用辅助函数来读取和丢弃所有保留在'\n'中的字符。例如,如果您打算输入stdin,但是Cat踩在键盘上,将stdin留在输入缓冲区中,在阅读'a'后,以下字符仍为"asdfdeeees"。您需要一种简单的方法来丢弃剩余的所有字符。

以下提供了一个名为'a'的简单辅助函数,通过持续读取直到遇到"sdfdeeees\n"empty_stdin(它可以返回最后一个字符(或{{ 1}})允许检查用户在Linux上使用 Ctrl + D 或在windoze上使用 Ctrl + Z 手动取消输入。

'\n'

示例使用/输出

下面是一个会话的输出,其中单个字符,多个字符(并且根本没有字符,只需返回,并且每个可能的方案都处理没有问题:

EOF

仔细检查,查看所有答案,并戴上会计师帽子。在再次提示输入更多输入之前,查看每个成功的方法,考虑缓冲区中的所有字符。同样重要的是检查EOF,这是用户在不使用#include <stdio.h> /* helper function - empty all chars that remain in stdin */ int empty_stdin() { int c = getchar(); /* get 1st char remaining in stdin */ while (c != '\n' && c != EOF) /* while not '\n' or EOF, get next */ c = getchar(); return c; } int main (void) { while (1) { /* infinite loop for input */ int c; printf ("Enter a character (press q to exit): "); c = getchar(); /* read character */ if (c == '\n') /* is it a newline? */ continue; /* if so, continue */ if (c == EOF) { /* end-of-file, from ctrl+d, or ctrl+z (windoze) */ putchar ('\n'); /* tidy up with \n */ break; /* bail */ } if (c == 'q') /* did user quit? */ break; /* bail */ printf ("'%c' is integer: %d\n", c, c); if (empty_stdin() == EOF) { putchar ('\n'); /* tidy up with \n */ break; } } return 0; } 或生成$ ./bin/getchar_min Enter a character (press q to exit): A 'A' is integer: 65 Enter a character (press q to exit): BC and other stuff 'B' is integer: 66 Enter a character (press q to exit): Enter a character (press q to exit): Z 'Z' is integer: 90 Enter a character (press q to exit): a 'a' is integer: 97 Enter a character (press q to exit): z 'z' is integer: 122 Enter a character (press q to exit): Q 'Q' is integer: 81 Enter a character (press q to exit): q 中断信号的情况下用信号取消输入的唯一方式。 Linux上的 Ctrl + C 。如果您有任何其他问题,请与我们联系。

修改

注意:我在捕获每个EOF后添加了一个“整理'q'”,以便在执行结束时提供正确的换行符(因此在最后一个提示符后,您的下一个终端提示符不会启动来自您的程序的输入 - 在终端SIGINT

的1/2路

答案 2 :(得分:1)

您只需更改行

即可
public static IEnumerable<int> BoyerMooreHorspoolIndexesOf(byte[] haystack, byte[] needle)
{
    if (haystack == null)
        throw new ArgumentNullException("haystack");

    if (needle == null)
        throw new ArgumentNullException("needle");

    int haystackLength = haystack.Length;
    int needleLength = needle.Length;

    if ((haystackLength == 0) || (needleLength == 0) || (needleLength > haystackLength))
        yield break;

    var misses = new int[256];

    for (var i = 0; i < 256; ++i)
        misses[i] = needleLength;

    var lastneedleByte = needleLength - 1;

    for (var i = 0; i < lastneedleByte; ++i)
        misses[needle[i]] = lastneedleByte - i;

    var index = 0;
    while (index <= (haystackLength - needleLength))
    {
        for (int i = lastneedleByte; haystack[index + i] == needle[i]; --i)
        {
            if (i == 0)
            {
                yield return index;
                break;
            }
        }

        index += misses[haystack[index + lastneedleByte]];
    }
}

printf("%d\n",c);

正如其他人指出的那样,你正在打印换行符。使用上面的“if”,您确保只打印不是换行符的字符。