【问题标题】:getchar() and buffer ordergetchar() 和缓冲区顺序
【发布时间】:2015-08-03 16:07:49
【问题描述】:

我正在阅读的一本初学者的 C 书籍让我对 getchar() 和缓冲区顺序(尤其是与换行符有关)感到困惑。它说,

摆脱 Enter 键是所有 C 初学者都必须面对的问题。考虑以下程序段:

printf("What are your two initials?\n");
firstInit = getchar();
lastInit = getchar();

您会认为如果用户键入GTG 将进入变量firstInit,而T 将进入lastInit,但事实并非如此。第一个 getchar() 直到用户按 Enter 才完成,因为 G 将进入缓冲区。只有当用户按下 Enter 时,G 才会离开缓冲区并进入程序——但是 然后 Enter 仍然 在缓冲区中!因此,第二个 getchar() 将该 Enter (\n) 发送到 lastInitT 仍然留给后续的getchar()(如果有的话)。

首先,我不明白作者对为什么\n 转到lastInit 而不是T 的解释。我猜是因为我将缓冲区可视化为“先进先出”。无论哪种方式,我都不明白作者呈现的顺序背后的逻辑——如果用户输入G,然后输入T,然后输入,G 是如何被第一个getchar() 捕获的, Enter(换行符)被第二个getchar()捕获,T被第三个getchar()捕获?令人费解。

其次,我自己尝试了这个(Ubuntu 14.04 在 Windows 8.1 下的 VMWare 上运行,文本编辑器 Code::Blocks,编译器 gcc),我得到了作者所说的确切常识结果 不发生!:G 转到 firstInitT 转到 lastInit。这是我的代码:

#include <stdio.h>

main()
{
  char firstInit;
  char lastInit;

  printf("What are your two initials?\n");

  firstInit = getchar();
  lastInit = getchar();

  printf("Your first initial is '%c' and ", firstInit);
  printf("your last initial is '%c'.", lastInit);

  return 0;
}

输出是:

What are your two initials?
GT
Your first initial is 'G' and your last initial is 'T'.

我还创建了一个后续程序,它似乎确认换行符最后从缓冲区中出来:

main()
{
  char firstInit;
  char lastInit;
  int newline;

  printf("What are your two initials?\n");

  firstInit = getchar();
  lastInit = getchar();
  newline = getchar();

  printf("Your first initial is '%c' and ", firstInit);
  printf("your last initial is '%c'.", lastInit);
  printf("\nNewline, ASCII %d, comes next.", newline);

  return 0;
}

输出是:

What are your two initials?
GT
Your first initial is 'G' and your last initial is 'T'.
Newline, ASCII 10, comes next.

所以我在这里遗漏了什么还是作者错了? (或者这个编译器依赖——即使作者没有这么说)?

书籍:C Programming Absolute Beginner's Guide,第 3 版,Greg Perry,©2014,Ubuntu 14.04,gcc 编译器版本 4.8.4

【问题讨论】:

  • 尝试输入“GT”。
  • @AndrewHenle 我只能在程序终止之前输入 G 。在这种情况下 firstInit 捕获 G 而 lastInit 捕获换行符,这是我所期望的。
  • 只需输入“GT”。 BTW main 定义不正确,应该是 int main(void)
  • 是的。你几乎证实你的书是错的。不,我不知道它在任何上下文中是正确的,但是很难证明它在作者写的时候是不正确的。
  • @WeatherVane 嗨,正如我在问题中解释的那样,我确实输入了 GT,得到的结果与作者所说的不同,这就是我问这个问题的原因。关于 main 的定义不正确,我是一个初学者,只是按照书中的格式(他没有说任何关于 int main(void) 的内容。谢谢。

标签: c getchar


【解决方案1】:

作者在描述用户输入“GT”的场景。

【讨论】:

  • 这当然可以解释它,你可能是对的,这是作者的意图。但在我看来,这种措辞具有误导性:“......如果用户键入 GT”与“......如果用户键入 GT”不同。谢谢。
【解决方案2】:

这是一个不同的例子。菜单循环将针对每个输入的 1、2 或 3 选项进行两次迭代。
//while ( ( getchar ( ) != '\n')) {} 中删除注释//,每个条目后缓冲区将被清除,并且每个条目菜单只会循环一次。

#include <stdio.h>

int main()
{
    char *menu[] = { "1. first", "2. second", "3. third", "4. Exit"};
    int choice = 0;
    int each = 0;

    do {
        for ( each = 0; each < 4; each++) {
            printf ( "%s\n", menu[each]);
        }
        printf ( "\tenter choice 1-4\n");
        choice = getchar ( );
        //clear the buffer
        //while ( ( getchar ( ) != '\n')) {}
        printf ( "you entered %d %c\n", choice, choice);
    } while ( choice != '4');
    return 0;
}

【讨论】:

  • 谢谢,我试试看!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-23
  • 2014-07-31
  • 2021-11-08
  • 1970-01-01
  • 2013-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多