【问题标题】:getchar() function in C: why it won't print a character right after I use getchar?C中的getchar()函数:为什么在我使用getchar后它不会立即打印字符?
【发布时间】:2013-01-19 06:20:57
【问题描述】:

我只是编程的初学者。我正在学习 K&R 的书,C 编程语言。在阅读的过程中,我对这个问题越来越好奇—— 当有一个循环从输入中逐个获取字符时,我在循环中放置了一个输出函数,我认为其结果就像在输入每个字符后立即打印它。但是,结果似乎只有在我点击一个键后计算机才会打印出一整套字符。

如K&R书中练习1-22的答案:

/* K&R Exercise 1-22 p.34 
 *
 * Write a program to "fold" long input lines into two or more
 * shorter lines after the last non-blank character that occurs before the n-th
 * column of input.  Make sure your program does something intelligent with very
 * long lines, and if there are no blanks or tabs before the specified column.
 */

#include <stdio.h>

#define LINE_LENGTH 80
#define TAB '\t'
#define SPACE ' '
#define NEWLINE '\n'

void entab(int);

int main()
{
    int i, j, c;
    int n = -1;     /* The last column with a space. */
    char buff[LINE_LENGTH + 1];

    for ( i=0; (c = getchar()) != EOF; ++i )
    {
        /* Save the SPACE to the buffer. */
        if ( c == SPACE )
        {
            buff[i] = c;
        }
        /* Save the character to the buffer and note its position. */ 
        else
        {
            n = i;
            buff[i] = c;
        }

        /* Print the line and reset counts if a NEWLINE is encountered. */
        if ( c == NEWLINE )
        {
            buff[i+1] = '\0';
            printf("%s", buff);

            n = -1;
            i = -1;
        }
        /* If the LINE_LENGTH was reached instead, then print up to the last
         * non-space character. */
        else if ( i == LINE_LENGTH - 1 )
        {
            buff[n+1] = '\0';
            printf("%s\n", buff);

            n = -1;
            i = -1;
        }
    }
}

我想程序会变成这样,它只会打印出一行长度为 80 的字符,就在我输入了 80 个字符之后(我还没有点击 ENTER 键)。然而,它并没有以这种方式出现!无论有多少字符,我都可以完全输入整个字符串。当我最终决定结束这一行时,我只需点击 ENTER 键,它就会给我正确的输出:长字符串被切割成几个短的片段/行,它们有 80 个字符(当然最后一个可能包含更少超过 80 个字符)。

我想知道为什么会这样?

【问题讨论】:

  • 输入被缓冲,你的程序只有在用户输入换行符后才会接收它(或者如果系统缓冲区已满)。
  • 为什么这个标签是C++
  • 从表面上看,这个问题与 C++ 无关。
  • @DanielFischer 谢谢。我现在有点明白了。但是为什么不改变 buff[] 字符串呢?计算机不仅可以打印一个 buff[] 字符串,而我认为只有最新更新的 buff[] 字符串可以保留。程序中只定义了一个 buff[] 字符串。或者我可以说,整个结果都被抛光了,只是等待换行符显示出来?

标签: c input inputstream getchar


【解决方案1】:

通常(在您的情况下),stdin 是行缓冲的,因此您的程序不会在输入字符时接收字符,而是在用户输入换行符时以块的形式接收(Return kbd>),或者,当系统缓冲区已满时。

因此,当用户输入最终发送到您的程序时,它会被复制到程序的输入缓冲区中。这就是getchar() 读取字符以填充buff 的地方。

如果输入足够长,buff 将被输入缓冲区中的LINE_LENGTH 字符填充,然后打印几次(直到输入缓冲区的全部内容都被消耗完)。

在 Linux 上(我认为通常在 Unix-ish 系统上,但我不确定),您还可以通过键入 Ctrl+D 将输入发送到程序而无需输入换行符 在非空行上(作为行上的第一个输入,关闭stdin;在输入行的稍后位置,您可以通过键入两次来关闭stdin),所以如果您键入Ctrl+D 在输入LINE_LENGTH [或更多] 个不带换行符的字符后,[至少初始部分] 输入会立即打印出来。

【讨论】:

  • 谢谢!我想我现在明白了。 :) 在学习 C 时了解计算机的工作原理很重要...
【解决方案2】:

很高兴在这里见到你,因为我也来自中国。事实上,我的英语很差。而且,我也是编程的初学者。所以,我不太了解你的目的。

但是,我在您的代码中发现了一个问题。循环可能不会停止。 EOF 是文件结尾,但您没有打开任何文件。

我对 getchar() 的了解是将标准输入获取到黄油缓存中。 getchar() 常用于停止输入(或循环)。

希望我的回答能帮到你。

【讨论】:

  • 这其实不是我这里附的代码,只是我在网上找到的一个程序。而且,是的,EOF 是读取文件的终结符,然而,这里的“文件”不仅仅是指计算机中的一个文档,更像是一个数据流。另外:“在 C 标准库中,getchar 等字符读取函数返回一个等于符号值(宏)EOF 的值,表示出现了文件结束条件。” (见:EOF in wikipedia)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多