首页 > 解决方案 > getchar 的奇怪行为,这是实现定义的行为吗?

问题描述

我正在尝试打印一个整数平方表。目的是编写一个程序,在每 24 个方格后暂停,并要求用户打印 Enter 以继续。这并不太复杂,我已经用 C 语言“完成”了手头的任务。

我的担忧:当我编译和运行以下代码时,会出现一个看似无关紧要(但可以观察到)的小问题:

    #include <stdio.h>

    int main()
    {
      int i, n;

      printf("This Program prints a table of squares. \n");
      printf("Enter number of entries in table: ");
      scanf("%d", &n);

      for(i = 1; i <= n; i++) {
        if((i - 1) % 24 == 0 && i > 1) {
          printf("Press Enter to continue...");
            while(getchar() != '\n')
             ;   
        }   
        printf("%10d%10d\n", i, i*i);
      }

    }

我的输出是完美的,正是我想要的,除了24 的第一个倍数(即 24)。出于某种原因,如果我选择一个大的 n,表格将完美打印出来,但只需要我从 48 开始按 Enter,第一个 printf 输出很奇怪,它不需要用户按任何键(更不用说 Enter )。它看起来像这样:

            24       576
    Press Enter to coninue...        25       625
            26       676

但是下次代码使用 printf 时,一切似乎都很完美,我需要按 Enter 继续,因为它应该是..(代码中稍后的健康输出示例以及所有后续的 24 倍数) .

            48      2304
    Press Enter to coninue...
            49      2401

纠正这一点的一件事是,如果我在 for 循环中的 printf 和 while 之间放置了一个额外的 getchar() 函数。所以代码完全一样,除了 for 循环现在看起来像这样:

for(i = 1; i <= n; i++) {
    if((i - 1) % 24 == 0 && i > 1) {
      printf("Press Enter to continue...");
      getchar();
        while(getchar() != '\n')
         ;   
    }   
    printf("%10d%10d\n", i, i*i);
  }

在这种情况下,代码运行完美。除了从 48 开始我需要按两次 Enter 键。大概这是因为我已经设置了额外的 getchar() 但是为什么我只需要在 i = 24 时按一次 Enter 呢?

我的猜测是这与(i - 1) % 24论点有关,但我看不出问题出在哪里。这是 KNK C Programming A Modern Approach 第 7 章中的一个问题。我是一名自学成才的程序员。我希望我的问题易于理解,并且它阐明了关于 C 的一些重要内容。这可以被视为实现定义的行为吗?也许在另一台机器上我所描述的不会发生?如果不是,为什么不呢?

标签: c

解决方案


在调用 之后scanf,输入缓冲区中会留下一个换行符。这个换行符在第一次调用时被拾取,getchar导致它跳出while循环。

您想在scanf调用后通过循环使用换行符,getchar直到获得换行符。

scanf("%d", &n);
while (getchar() != '\n');

推荐阅读