5

私のCコード:

int c;
c = getchar();

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

なぜこのプログラムは入力時にこのように反応するのhelloですか?

hello
hello

好きではない:

hheelloo
4

6 に答える 6

5

入力すると、コンソールがキーボードからの出力を取得し、エコーバックします。

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;
}
于 2011-06-21T14:25:55.113 に答える
5

あなたの入力は正しくhelloありませんか?h e l l o

したがって、入力は を押すまでバッファリングされますenter

于 2011-06-21T14:17:53.463 に答える
3

Enter キーを押したとき、端末はおそらく入力を stdin に書き込むだけです。何かを入力してみて、バックスペースして別の何かを書いてください。最初に入力した文字が表示されない場合は、データをプログラムに送信する前に、端末が行を作成するのを待っていたことを意味します。

生の端末アクセスが必要な場合 (キーダウンとキーアップに反応するなど)、ncursesなどの端末ライブラリを試す必要があります。

于 2011-06-21T14:17:07.203 に答える
1

stdinキーボードを参照するときのデフォルトはラインバッファリングされるためです。
つまり、単一の文字ではなく、完全な行のみが表示されます。

あなたがあなたの友人に彼の電話番号が何であるかを尋ねると想像してください...しかし彼はそれを一枚の紙に書き留めなければなりません。彼が書いているように、あなたは数字ごとに数字を取得しません:彼があなたに一枚の紙を与えるとき、あなたはすべての数字を取得します:)

于 2011-06-21T14:23:31.893 に答える
1

標準入出力ストリームはバッファリングできます。つまり、空白文字 (たとえば) が検出されるまで、入力が画面にエコーされない場合があります。

于 2011-06-21T14:15:54.687 に答える
0

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();
    }
}
于 2011-06-21T14:31:52.563 に答える