3

我想读取两个字符,所以我执行以下代码:

main() {
    char a,b;

    printf("\nEnter the first char.. ");
    a=getchar();
    printf("\nEnter the second char.. ");
    b=getchar();
    b=getchar();       //<--I've to add this sentence because the previously doesn't work

    printf("\nFirst char --> %c",a);
    printf("\nSecond char --> %c",b);

}

该代码不应该工作,但确实可以。输出是正确的:

第一个字符 --> z

第二个字符-> z('z'或我想要的字符)

如果我删除第二个getchar(),那么输出是:

第一个字符 --> z

第二个字符 --> (这里没有字符)

如何删除第二个getchar()而不会出现任何错误?

因为fflush(stdin)之前getchar()不行。

4

4 回答 4

7

试试这个:制作一个文件data,大小为两个字节,精确包含ab. 现在说:

./myprogram < data

瞧。

关键是,当您操作终端并按下a回车键时,您正在向进程发送两个字符,首先是换行符a,然后\n是换行符。所以第二个getchar拿起换行符。

(并且您的终端不允许您在不按 Enter 的情况下发送单个字符,因为它有一个行缓冲区,在发送任何内容之前它会填满。)

简而言之,getchar它是一个糟糕的 I/O 原语,您几乎应该总是喜欢fgets阅读整行并处理它们。

于 2012-08-05T23:18:07.903 回答
2

如其他答案所示,问题是由回车引起的。

有很多方法可以解决这个问题,有些方法比其他方法更复杂。因此,我将指出我发现的最简单的方法:

正如GNU 网站指出的那样,最合适的功能是getc(stream),我引用:

这就像fgetc,除了它是允许的(并且是典型的)它被实现为一个不止一次评估流 参数的宏。getc通常是高度优化的,因此它通常是读取单个字符的最佳函数

我将它付诸实践,但它仍然存在CR问题,所以我打印了这个函数的结果,并注意到它在 CR 时返回 10。在此之后,我试图获得代码的功能和清晰度。为此尽一切可能,现在我的代码如下:

main() {
    char a,b;

    printf("\nEnter the first char.. ");
    if ((a=getc(stdin))==10) a=getc(stdin);
    printf("\nEnter the second char.. ");
    if ((b=getc(stdin))==10) b=getc(stdin);

    printf("\nFirst char --> %c",a);
    printf("\nSecond char --> %c",b);

}

和不错的输出:

第一个字符 --> z

第二个字符-> z('z'或我想要的字符)


我了解到所有程序都需要他们自己的解决方案,与其他程序不同,这就是(我认为)功能如此之多的原因。我能说的是“总是要适应程序。也许这句话对我有用,但不能保证适用于其他代码。”

感谢所有帮助过我的人!

于 2012-08-06T04:09:00.433 回答
1

听起来您的getchar()函数将换行符留在键盘缓冲区中。这意味着第一个b=getchar();读取换行符,第二个读取您期望的实际输入。如果您有可用的功能,更优雅的方法是忽略换行符ignore()

于 2012-08-05T23:18:35.467 回答
0

getchar()只获取一个字符。换行符需要一个字符,因此您需要在代码中使用额外的 getchar() 才能获得所需的输入/输出。

于 2012-08-05T23:18:53.817 回答