- ベストアンサー
単語検索プログラム
論文の中から入力された単語を探し出し、その単語が含まれる行を表示させるというプログラムを作りたいのですが、うまくいきません。下に私が作ったプログラムを載せておくのでどこをどうすればいいのかを指摘してください。お願いします。 #include <stdio.h> #include <string.h> #define NUM_LINE 26 #define NUM_COL 128 int main(void){ char text[NUM_LINE][NUM_COL]={ " Four score and seven years ago our fathers brought forth", "on this continent, a new nation, conceived in Liberty, and", "dedicated to the proposition that all men are created equal.", " Now we are engaged in a great civil war, testing whether", "that nation, or any nation so conceived and so dedicated,", "can long endure. We are met on a great battle-field of that", "war. We have come to dedicate a portion of that field, as a", "final resting place for those who here gave their lives that", "that nation might live. It is altogether fitting and proper", "that we should do this.", " But, in a larger sense, we can not dedicate -- we can not", "consecrate -- we can not hallow -- this ground. The brave", "men, living and dead, who struggled here, have consecrated", "it, far above our poor power to add or detract. The world", "will little note, nor long remember what we say here, but", "it can never forget what they did here. It is for us the", "living, rather, to be dedicated here to the unfinished work", "which they who fought here have thus far so nobly", "advanced. It is rather for us to be here dedicated to the", "great task remaining before us -- that from these honored", "dead we take increased devotion to that cause for which", "they gave the last full measure of devotion -- that we here", "highly resolve that these dead shall not have died in", "vain -- that this nation, under God, shall have a new birth", "of freedom -- and that government of the people, by the", "people, for the people, shall not perish from the earth." }; char line[100]; int i, j, k, length; printf("> Search for "); fgets(line, sizeof(line), stdin); for(i = 0; line[i] != '\n'; i++){ length++; } for(k = 0; k < length; k++){ for(i = 0; i < NUM_LINE; i++){ for(j = 0; j < NUM_COL; j++){ if(text[i][j + k] == line[k]){ } } printf("%d: %s\n", i, text[i]); } printf("\n"); } return 0; }
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
ヒントだけ ・lengthの初期値はいくつですか? 宣言しただけの変数の内容は不定です。 ・ループの順序がおかしいです。 もう一度よく見直してください。 また、一文字の単純宣言は認識間違いを起こす要因になります。 line_countなどわかリやすい変数名にしましょう。 ・if()文が成立している際の処理がありません。 この部分では何を行いたいのですか? この部分の処理によって、下の行のprintf()の処理の仕方が違ってきます。 ・c言語の「文字列」の定義は理解していますか? text[][]の一行の最後はどのように判断する必要があるか考えましょう やらなければいけないことは、 「textのn行目の文字列がline[]の内容と一致しているか」です。 一行の確認する範囲は行の先頭「text[n][0」」から「(一行の文字列の長さ-line[]の長さ)+1」までです。 text[n]の残りの文字数がline[]の文字数より短くなれば以降は確認する必要がありません(確認してもいいですが、一致することはないのでやるだけ無駄なことは理解できると思います)。 ここはご自分でよく考えてみてください。 一行目が text[]="11234567890" だったとします。 検索する文字列は line="1234"の場合、最初の確認で一文字目は一致しますが二文字が一致しません。 従って、次のtext[]の検索位置は二文字目、line[]は一文字目からやり直す必要があります。 この部分をどう処理するかが、この質問の重要な箇所になります。
その他の回答 (3)
- Tacosan
- ベストアンサー率23% (3656/15482)
「単語」はどのように定義してますか? 与えられた文字列データは中でいじくってかまいませんか? やっていいなら ・テキスト中の「単語に含まれない文字」をすべて空白に変えて ・テキストの先頭と末尾に空白と追加して ・検索したい単語の先頭と末尾にも空白を追加して ・strstr を使う というのが組みやすいかな.
- yama5140
- ベストアンサー率54% (136/250)
>下に私が作ったプログラムを載せておくのでどこをどうすればいいのかを指摘してください。 申し訳ない、「どこをどうすれば」の指摘ではありません。 +++++++++++++++++++++++++++++++++++++ 結論:年寄りには、噛みごたえがありました。 ( No.2 さんの) >line の改行を '\0' にして strstr() 関数を使ってはどうでしょう と私も考えたのですが、strstr() 関数を使うとなると、例えば、 "on" が検索文字列の場合、"on" が含まれる "continue" や "nation" の処理を考えないと・・・。 かつ、"on" が対象文字列の先頭・終端にある場合の・・。 そこで、 1.入力した検索文字列の「改行」を「 '\0' 」に変更(以降 s0 と表記)。 2.全行をサーチ( strstr( text[ i ], s0 ) )。 3.2の過程で、NULL でない行を再び、 ( continue や nation を、他の単語として除外するため) ・s0 の頭にスペース1つ付けたもの・・s1 " on" ・s0 の後にスペース1つ付けたもの・・s2 "on " ・s0 の前後にスペースを付けたもの・・s3 " on " で、strstr( text[ i ], sx ) すると、 s1 は、on が、対象文字列の終端にある場合のみ正しく検索可能。 s2 は、on が、対象文字列の先頭にある場合のみ正しく検索可能。 s3 は、on が、対象文字列の中間にある場合のみ正しく検索可能。 となり、strstr( text[ i ], sx ) の「戻り値」を用いたコード化は・・硬すぎる(せんべいか?)。 ++++++++++++++++++++++++++++++++++++++ (長々と書いたけど・・) ☆やっぱ、strstr() 関数を使わずに、1文字ずつ検索かな。 http://okwave.jp/qa4434950.html No.6 を改造しました。 スリムにしようとしたら、「グローバル」変数ばっかで・・。 (BorlandC++5.6.4) a や on や not ( note, 行末の not ) でお試し下さい。 #include <stdio.h> #define NUM_LINE 26 #define NUM_COL 128 char *cgTarget, *cgKensak; // グローバル変数 int igEQ_Cnt = 0; // グローバル変数 void Fuicchi( char *cLine ) { cgTarget++; cgKensak = cLine; // 検索文字列リセット igEQ_Cnt = 0; } int FindPrint( int iGyo, char *cText, char *cLine ) { cgTarget = cText; // 対象文字列 cgKensak = cLine; // 検索文字列( '\n' 付き) while( '\0' != *cgTarget ){ // 対象文字列が終わるまで if( *cgTarget != *cgKensak ){ // 文字不一致 Fuicchi( cLine ); continue; } if( ! igEQ_Cnt ){ // 初一致で if( cgTarget != cText ){ // かつ、行頭でない時 cgTarget--; // 前文字へ if( ' ' != *cgTarget ){ // 前文字がスペースでない Fuicchi( cLine ); cgTarget++; continue; } cgTarget++; } } cgTarget++; // 次の文字は? cgKensak++; igEQ_Cnt++; if( '\n' == *cgKensak ){ // 検索文字列終わり if( ( ' ' != *cgTarget ) && ( '\0' != *cgTarget ) ) return( 0 ); printf( "[%03d]%s\n", ++iGyo, cText ); // 行番号付き結果出力 return( 1 ); } if( *cgTarget != *cgKensak ){ // 次の文字不一致 Fuicchi( cLine ); } } return( 0 ); } int main( void ) { ・ (略) ・ char line[100]; int i; printf( "> Search for " ); fgets( line, sizeof( line ), stdin ); for( i = 0; i < NUM_LINE; i++ ){ FindPrint( i, text[ i ], line ); } return( 0 ); } 注:インデントに全角空白を用いています。タブに一括変換して下さい。
- php504
- ベストアンサー率42% (926/2160)
string.hをincludeしてますが使ってないようですね lineの改行を'\0'にしてstrstr( )関数を使ってはどうでしょう 大文字小文字を無視するならさらに処理が必要です