2011-12-15 3 views
5

これはスタックオーバーフローに関する私の最初の投稿です。だから私は誰の足元にも足を踏み入れていないことを願っています。もちろんK&R:第6章 - getword()関数がEOFを読み込まないのはなぜですか?

は、すべての入力は歓迎と感謝しているが、その答えに最も適したものが実際に持っている書籍、プログラミング言語C第2版を読んでいました。

は、私はちょうど練習6-4のコーディングが終了したが、私は何かを把握するように見えることはできません。 Ctrl + D(Arch Linux VMでC言語でコード化)を押すまで、getword()関数がEOFを読み込まないのはなぜですか?本からの私の前の演習の

多くは、標準入力からの読み込みが必要です。私がやる方法の1つは、

while ((c = getchar()) != EOF) {...} 

です。このような場合、Ctrl + Dを押す必要はありません。入力した内容を入力してEnterキーを押すと、stdinバッファがフラッシュされ、EOFが自動的に検出されます。 getword()関数もgetchar()をベースにしているので、なぜプログラムがハングしますか?

getword()関数から呼び出される)(メイン:

while (getword(word, MAX_WORD) != EOF) { 
    if (isalpha(word[0])) { 
     root = addtree(root, word); 
    } 
} 

getword()関数自体:私はEOFであると判定点を示すために、コメントを入れ

int getword(char *word, int lim) { 

    char *w = word; 
    int c; 

    while (isspace(c = getch())) { 
    } 
    if (c != EOF) { 
     *w++ = c; 
    } 
    // This point is reached 
    if (!isalpha(c)) { 
     // This point is never reached before Ctrl+D 
     *w = '\0'; 
     return c; 
    } 
    for (; --lim > 0; w++) { 
     if (!isalnum(*w = getch())) { 
      ungetch(*w); 
      break; 
     } 
    } 
    *w = '\0'; 
    return word[0]; 
} 

読まれていない。

getchは()とungetch()関数は、第4章からポーランド記法の計算で使用したのと同じものである(そのプログラムが自動的にEOFを読み取ることができた - Enterキーを押して):

#define BUF_SIZE 100 

char buf[BUF_SIZE]; 
int bufp = 0; 

int getch(void) { 

    return (bufp > 0) ? buf[--bufp] : getchar(); 
} 

void ungetch(int c) { 

    if (bufp >= BUF_SIZE) { 
     printf("ungetch: too many characters\n"); 
    } 
    else { 
     buf[bufp++] = c; 
    } 
} 

従ってこれは私がCtrl + Dで手動でEOFを入力する必要がある本書の冒頭から書いた最初のプログラムです。私は理由を理解できないようです。

説明については、事前に多くの感謝...あなたが入力したタイプのようなもの句読点をした場合

+0

コードを書式設定するには、コードをハイライト表示し、 '{}'アイコンをクリックします。これは、強調表示された領域を4つのスペースでインデントします。これは、 "markdown"がソースコードをどのように示しているかを示します。 [編集ヘルプページ](http://stackoverflow.com/editing-help)も参照してください。私はあなたのためにそれを修正しました。そして、Stackoverflowへようこそ! –

答えて

3

EOFを取得するためにCtrl + Dキーを押すことは、Unixライクなシステムの通常の動作です。あなたのコードスニペットの場合

を押す

while ((c = getchar()) != EOF) {...} 

は(あなたのtty設定はひどく台無しにされていない限り)間違いなくがループを終了してはならないを入力します。

すると、このプログラムをコンパイルして実行してみてください:

#include <stdio.h> 
int main(void) 
{ 
    int c; 
    while ((c = getchar()) != EOF) { 
     putchar(c); 
    } 
    return 0; 
} 

それはあなたが入力し、すべてを印刷する必要があり、それはあなたが行(またはとき、あなたがコントロールしてそれを殺すの先頭に制御-Dを入力した場合にのみ終了する必要があります-C)。

+0

または、2つのcontrol-Dを連続して入力します。または、あなたが 'quit'シグナルでそれを殺すとき。 :D –

+0

ありがとうございます。私は自分のコードを再検討し、あなたは正しいです。 Enterキーを押すと、sdtinバッファが画面に流出しますが、Ctrl-DまたはCtrl-Cを押すまで、EOFは決して遭遇しません。 私は何とかEOFを '\ n'と混同しました。 –

2

「到達していない」ポイントしか到達できます - またはあなたがEOFをお読みください。文字またはスペースを入力すると、バイパスされます。

あなたはコントロール-D(または任意stty -a出力で指定されている)を使用すると、別のヒットあなたは改行を入力した後、または後を入力するまで入力は、次に、EOFが検出されていない端末(標準入力)から来ている場合Control-D(2行で)改行文字は、改行文字'\n'isspace()を満たすため、コードを読み込みます。

+0

あなたはまた、非アルファベットを入力すると、私が指摘したポイントに到達することがControl-Dの前に決して届かないということも正しいです。私は言葉の文脈の中でのみ言葉を考えていました。 –

0

私の以前のプログラムに対する私の混乱の原因は、私の以前のプログラムの効果が常にの内側にあるのwhileループに印刷されていることでした。したがって、私はいつもすぐにEOF 。このため、whileループが終了するまでツリーは印刷されないため、EOFの出会いが必要でした。私はそれを認識することができませんでした、そして、それが私が狂ってしまった理由です。

私をまっすぐにしてくれてありがとう!

関連する問題