質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

4686閲覧

EOFがうまくいきません

Teemro_431265

総合スコア29

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/10/20 08:33

編集2018/10/20 12:37

標準入力から入力した文字とファイルから読み込んだ文字を比較してCtrl+Dを入力したらループを抜け出せるものを作っていたのですが、このコードだと抜け出せるものの実行結果が次のようになってしまいます。自分はこれでいけると思っていたので何を直せばいいのかわかりません。
実行結果
Input a word: zoo
The words zoo is found.
Input a word: daf
The words daf is not found.
Input a word: The words daf is not found.
Input a word: The words daf is not found.
Input a word: The words daf is not found.
Input a word: The words daf is not found.
Input a word: The words daf is not found.




このまま最後の文がかなり長く続いて元のコマンド入力待ちの状態にもどります。なぜ最後の行が何十行も続くのでしょうか、fgetsでNを100に定義しているのと関係ありそうな気はしているのですが何を直せばいいのかわかりません。

c

1#include<stdio.h> 2#include<stdlib.h> 3#include<string.h> 4#define N 100 5 6int main(){ 7 int i; 8 char input[N],buf[N],*in,*bu,c; 9 FILE *fp; 10 11//printf("%s\n",input); 12 if((fp=fopen("words","r"))==NULL){//読み込んだ値をfpに代入 13 exit(1); 14 } 15//文字列を一つずつコピーしていき、比較する 16i=0; 17 while(1){ 18 fgets(buf,N,fp); 19 strtok(buf,"\n"); 20 if(buf[i]==EOFbreak; 21 bu=buf; 22 //printf("%s\n",bu); 23 24 printf("Input a word: "); 25 fgets(input,N,stdin); 26 strtok(input,"\n"); 27 in=input; 28 29 if(strcmp(in,bu)==0){ 30 printf("The words %s is found.\n",input); 31 } 32 else{ 33 printf("The words %s is not found.\n",input); 34 } 35 i++; 36 } 37 fclose(fp); 38 return 0; 39}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

まず、 katoyさんの書かれたように、 fgets()関数の使い方確認をされる事を勧めます。

strtok(buf,"\n");

こちらについても目的が分かりませんが、行の分割でしょうか? もし、そうならば、fgets()が行単位で読み込む事が理解されていないと思います。

if(buf[i]==EOF)break;

こちらは、ファイルの最後まで読み込んだ事の確認と思われますが、読み込んだ文字列中に EOF(-1)が来る事はあり得ません。(バイナリだったら、、はありますが)
fgets()の読込みが失敗した場合、buffの値は保証されませんが、大体は、そのままの事が多いと思われます。 ---> 最後の行が連続して出力される理由。

EOF検出には、feof関数もあり、そちらでの確認もありますが、この関数は、EOF状態で無いと、検出しないという問題があり、ちょっと使いづらい。 fgets()の後で、feof() して fgets()がEOFで無い事の確認には使えるでしょうか。

投稿2018/10/20 10:29

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Teemro_431265

2018/10/20 12:29

strtok(buf,"\n");を入れた理由としてはfgetsを使った際%sの後になぜか改行が入ってしますので調べて見たらこれが出て来たので使っています。これを入れると改行がなくなるようです。
pepperleaf

2018/10/20 12:58

あ、行末の改行コードでしたか。ちょっと見落としていました。
guest

0

ベストアンサー

まずは、fgets を使って、ファイルを読み込み EOF を認識して、ファイルを閉じるコードをかいてください。
それができてから、 文字列を一つずつコピーしていき比較する 機能を追加するとよいです。

参考情報

  • fgetsで単純にファイルを読み取る

https://mementoo.info/archives/788

  • char * fgets( char *row , int len , FILE *fp )

http://hitorilife.com/fgets.php

...
■戻り値:
ファイルポインタfpから1行、またはlenバイト読み込んでその先頭アドレスを返す。
全行を読み込んだ場合、又はエラー時にNULL(\0)を返す。
...

追記:
変更例を示します。
(動作は質問文コードとは一致していませんが、ファイルからの読み込み、キーボードからの入力、改行コードの削除は動作しています)

c

1#include<stdio.h> 2#include<stdlib.h> 3#include<string.h> 4 5#define N (100) 6 7int main() { 8 FILE *fp; 9 char line[N], input[N]; 10 char *p; 11 12 if ((fp =fopen("words.txt", "r")) == NULL) { 13 printf("can not open words.txt\n"); 14 exit(1); 15 } 16 17 // 文字列を比較する 18 while (1) { 19 char* s = fgets(line, N - 1, fp); 20 if (s == NULL) { 21 break; 22 } 23 24 p = strchr(line, '\n'); 25 if(p != NULL) { 26 *p = '\0'; 27 } 28 printf("[%s]\n", line); 29 30 printf("Input a words: "); 31 fgets(input, N - 1, stdin); 32 p = strchr(input, '\n'); 33 if(p != NULL) { 34 *p = '\0'; 35 } 36 // printf("[%s]\n", input); 37 38 if (strcmp(line, input) == 0) { 39 printf("'%s' == '%s'\n", line, input); 40 } else { 41 printf("'%s' != '%s'\n", line, input); 42 } 43 } 44 fclose(fp); 45 return 0; 46}

投稿2018/10/20 09:32

編集2018/10/20 23:55
katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Teemro_431265

2018/10/20 13:24

while(fgets(buf, N, fp) != NULL) このような感じに書くことはわかったんですけど、これだとstrtok(buf,"\n");が適用(?)されなくなってしまいprintf("%s",input);の後に謎の改行が入ってしまいます。
katoy

2018/10/20 23:00

改行コードを削除する方法例を追記しました。
Teemro_431265

2018/10/21 02:39

なるほど、ありがとうございます。
Teemro_431265

2018/10/21 09:13 編集

できないことはないのですがCntr+Dを押すと残りの単語も全て比較するものになってしまいました、文字列に入っている文字列の初期化みたいなのってできないですよね?
katoy

2018/10/21 10:16 編集

fgets(input, N - 1, stdin); を s = fgets(input, N - 1, stdin); if (s == NULL) { break; } に変更すれば Ctrl-D を入力すると、プログラム終了するようにできます。違う動作にしたければ、break の部分を書き換える必要があります。
Teemro_431265

2018/10/21 09:46 編集

その方法って文字列でも使うことができるんですか? 訂正 ポインタにすることで終了することができました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問