【问题标题】:getchar and putchargetchar 和 putchar
【发布时间】:2011-06-21 14:12:32
【问题描述】:

我的 C 代码:

int c;
c = getchar();

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

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

hello
hello

不喜欢:

hheelloo

【问题讨论】:

标签: c getchar


【解决方案1】:

您的输入是hello 而不是h e l l o 对吗?

因此,您提供的输入将被缓冲,直到您按 enter

【讨论】:

    【解决方案2】:

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

    getchar() 对输入流进行操作,该输入流通常配置为打开“规范输入”。这种配置减少了 CPU 轮询输入以获取缓冲方案的时间,在该方案中输入被缓冲,直到某些事件发生,通知缓冲区扩展。按下回车键(并按下控制 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;
    }
    

    【讨论】:

      【解决方案3】:

      您的终端可能只会在您按下回车时将您的输入写入标准输入。尝试输入一些内容,退格并写一些其他内容;如果您没有看到最初键入的字符,则表示您的终端在将数据发送到程序之前正在等待您编写行。

      如果您想要原始终端访问(例如,对按键和按键做出反应),您应该尝试一些终端库,例如 ncurses

      【讨论】:

        【解决方案4】:

        标准输入/输出流可以被缓冲,这意味着在遇到空白字符(例如)之前,您的输入可能不会回显到屏幕上。

        【讨论】:

          【解决方案5】:

          因为stdin 引用键盘时的默认值是行缓冲的。
          这意味着您只能看到整行,而不是单个字符。

          想象一下,你问你的一个朋友他的电话号码是什么……但他必须把它写在一张纸上。他写的时候你不会逐个数字地得到数字:当他给你一张纸时,你会得到所有的数字:)

          【讨论】:

            【解决方案6】:

            getchar 从输入流中读取输入,只有在按下 ENTER 键后才可用。到那时你只看到来自控制台的回显结果要达到你想要的结果,你可以使用这样的东西

            #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();
                }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-10-22
              • 1970-01-01
              • 2013-07-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-05-23
              相关资源
              最近更新 更多