getchar和putchar

5

我的C代码:

int c;
c = getchar();

while (c != EOF) {
    putchar(c);
    c = getchar();
}

为什么输入“hello”时,这个程序会有这样的反应?
hello
hello

而不是像这样:
hheelloo

4
这将是一个非常难以搜索的标题。 - Jake
1
由于太多人同时编辑了这个问题,几乎所有的编辑都在同一时间进行。 - Pindatjuh
2
可能是如何避免使用任何getchar()按Enter键的重复问题。 - Bo Persson
http://c-faq.com/osdep/cbreak.html - Artefacto
6个回答

7

您输入的是hello而不是hello,对吗?

因此,您输入的内容将被缓冲,直到按下enter键。


6

当您输入时,控制台会获取键盘输出并将其回显给您。

getchar() 操作的是一个输入流,通常配置为打开“规范输入”。这种配置减少了 CPU 轮询输入所花费的时间,采用缓冲方案对输入进行缓冲,直到发生某些事件,这些事件会触发缓冲区扩展。按下回车键(和按下 control D 键)都倾向于刷新该缓冲区。

#include <unistd.h>

int main(void){   
    int c;   
    static struct termios oldt;
    static struct termios newt;

    /* Fetch the old io attributes */
    tcgetattr( STDIN_FILENO, &oldt);
    /* copy the attributes (to permit restoration) */
    newt = oldt;

    /* Toggle canonical mode */
    newt.c_lflag &= ~(ICANON);          

    /* apply the new attributes with canonical mode off */
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);


    /* echo output */
    while((c=getchar()) != EOF) {
        putchar(c);
        fflush(STDOUT_FILENO);
    }                 

    /* restore the old io attributes */
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt);


    return 0;
}

4
您的终端可能只在按下回车键后将输入写入stdin。尝试输入一些内容,然后退格并再次输入;如果您看不到最初输入的字符,则意味着您的终端在发送数据给程序之前正在等待您组成行。
如果您想要原始的终端访问(例如响应按键和释放按键),您应该尝试使用像ncurses这样的终端库。

3
因为当stdin指向键盘时,默认情况下是行缓冲的。这意味着您只能看到完整的行,而不是单个字符。
想象一下,你问你的朋友他的电话号码是什么...但他必须把它写在一张纸上。你不能逐位获得号码,而是在他给你纸条时一次性得到所有数字 :)

1

标准输入/输出流可以进行缓冲,这意味着您的输入可能不会被回显到屏幕上,直到遇到空格字符(例如)为止。


0
getchar函数从输入流中读取输入,但只有在按下回车键后才可用。在此之前,您只能看到控制台上的回显结果。要实现您想要的结果,您可以使用类似以下代码的方法
#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int getCHAR( ) {
    struct termios oldt,
                 newt;
    int            ch;
    tcgetattr( STDIN_FILENO, &oldt );
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newt );
    ch = getchar();
    putchar(ch);
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
    return ch;
}
void main() {
    int c;
    c = getCHAR();
    while (c != 'b') {
        putchar(c);
        c = getCHAR();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接