2012-03-26 11 views
0

私は配列内の単語を検索するバイナリ検索機能を持っていますが、配列を検索する前に検索する単語を知る必要があります。ユーザーに入力を求めるコードを書いていますが、プログラムは入力要求を出力しますが、ユーザーから何も受け付けません。私はそれがバッファの問題だと思っていました。私は、プログラム内に初期のscanfがあり、外部ファイルからすべての文字列を読み込んで配列に配置しています。私は最初のscanfの後にfflushを使ってみました。そして、前のスレッドで指摘されているように、getsで2番目のものを書き直そうとしました。おそらく私はそれを正しく実装していないでしょう。ここで私はこれまで何をしているのか、2番目のscanfがうまくいかない理由についてのヒントを感謝します。Scanfが2番目の文字列を受け付けません

#include "set.h" 
#include "sortAndSearch.h" 
#include <stdio.h> 
#include <ctype.h> 
#include <string.h> 

int main(){ 
char names[320][30]; 
char str[30]; 
int i, j; 
char *key; 
int numOfWords; 
char userWord[30]; 
Set set1, set2, set3; 

//scan each char string into array names 
for(i=0; scanf("%s", str) != EOF; i++){ 
     strcpy(names[i], str); 
} 

//set number of words in file 
numOfWords = i; 

//sort names array 
//bubbleSort(names, numOfWords); 

//print out names, sorted 
//for(i=0; i<numOfWords; i++){ 
//  printf("%s\n", names[i]); 
//} 

printf("What word would you like to search for? "); 
scanf("%s", userWord); 

//addName2Set(set1, userWord); 

return 0; 
} 
+0

あなたが入力の*ライン*を読みたい場合は、行を読み込み、関数を使用します。さもなければ、あなたは単語を読んでいて、行末を残しています。 –

答えて

0

あなたの最初のループ内のscanf()はEOFまですべてを読み取るため、「あなたは何の単語を検索しますか?読むべきscanf()。この問題を回避

一つの方法は、(プログラム、または固定の名前の引数であるかもしれないfopen()fscanf()fclose() —およびファイル名)ファイルから最初の名前を読むことです。

もう1つの方法は、「What word」の前にclearerr(stdin);です。scanf()。それ(clearerr())はEOFビットの設定を解除し、scanf()の再試行を許可します。プログラムの入力が端末であれば動作します。プログラムの入力がファイルから来ている場合は役に立ちません。


int main(int argc, char **argv) 
{ 
    char names[320][30]; 
    char str[30]; 
    int i, j; 
    char *key; 
    int numOfWords; 
    char userWord[30]; 
    Set set1, set2, set3; 
    FILE *fp; 

    if (argc != 2) 
    { 
     fprintf(stderr, "Usage: %s word-file\n", argv[0]); 
     exit(1); 
    } 

    if ((fp = fopen(argv[1], "r")) == 0) 
    { 
     fprintf(stderr, "Usage: %s word-file\n", argv[0]); 
     exit(1); 
    } 

    //scan each char string into array names 
    for (i = 0; i < 320 && fscanf(fp, "%29s", str) != EOF; i++) 
    { 
     strcpy(names[i], str); 
    } 

    fclose(fp); 

    //set number of words in file 
    numOfWords = i; 

これは、あなたが./a.out example.dat(代わりの./a.out < example.dat)を使用することを主張しています。それはあなたが望むように多かれ少なかれ動作します。もちろん、ファイルを読むためのコードは、ファイル名、配列、および配列のサイズが渡される関数内になければなりません。ループ内の320はオーバーフロー保護であり、配列宣言とループの両方で使用される列挙型enum { MAX_WORDS = 320 };である必要があります。 29はオーバーフロー保護です。それをパラメータ化することは困難ですが、配列の2番目の次元より1つ小さいです。ご質問やコード

+0

なぜscanfはdata.datファイルの最後で終了しないのですか? – manalishi

+0

ファイル名は固定されておらず、プログラムの実行時に提供されます。./a.out manalishi

+0

'clearerr(stdin);'でもそのトリックを行いませんでした。最初の入力は外部ファイルから、2番目の入力は端末内からのものです。 – manalishi

4

あなたの最初のscanfが終了したことがないので、あなたの第二scanfは動作しません。 scanfは、入力ストリームが閉じられていない限り、EOFを返しません。これは、コンソールが閉じることになります。

scanfは読み込まれた文字数を返しますので、代わりにループ条件をscanf(%s, str) != 0にする必要があります。これは、ユーザーが何も入力せずにエンターを押すとすぐにループを終了させます。

+0

私は 'for(i = 0; scanf("%s "、str)!)を変更しました!= 0;私は+ +) 'しかし、今私はセグメンテーションフォールトを得る – manalishi

+0

外部ファイルから入力を取っているので、EOFはそこにあり、そのファイルにどれくらいのデータがあるかわからない。ユーザーは2回目のscanfまでプロンプトされません。 – manalishi

+0

「最初の」scanf()は決して実行しないとはどういう意味ですか?入力がファイルからリダイレクトされた場合(何が起こったかのコメントがあります)、ループはファイルの終わりまで繰り返しscanf()を実行します。入力が端末からのものであれば、Windowsではcontrol-Z、Unixではcontrol-Dを入力すると入力が終了します。どの場合でも、ループ内の 'scanf()'はうまく実行されます。 –

0

scanf()はあなたがfscanf()をしたい、あなたのファイルから読み込むための間違った機能である、またはファイルが各単語は自分自身であるようにフォーマットされている場合...一見すごくずれて見えました行fgets()も機能します(改行は各文字列の読み込みを停止します)。同様に、scanf()の代わりにgets()を使用すると、入力が単なる文字列で、それに続くreturn(改行)の場合にユーザー入力を読み取ることができます。

Everything you need to know about stdio.h

関連する問題