- ベストアンサー
ファイル入出力について教えて下さい。2
ご覧いただきありがとうございます。 何度も低レベルな質問で申し訳ありません。 A.PRMというファイルに、 I have a pen. He has a pen. と2行の文章が入っています。 これを読み取り、printfで画面表示させたいのですが、 #include <stdio.h> int main(void) { FILE *fp; char a[50]; char b[50]; if( (fp=fopen("A.PRM", "r" )) != EOF ) { fgets( a, 49, fp ); fgets( b, 49, fp ); } fclose( fp ); printf( "a = %s\n", a ); printf( "b = %s\n", b ); return 0; } とすると、fgetsで余分な改行が入ってしまいます。 fgetsの代わりにfscanfを使用すると、今度はスペースの前までしか読み込んでくれず、「a = I」「b = He」と表示されてしまいます。 どうしたらよいでしょうか? 是非ご回答いただきたいです。よろしくお願いいたします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
★最初に fopen 関数の戻り値は『NULL』でチェックします。 ・fgets で余分な改行が入りますので、strchr 関数などで検索して \0 文字に書き換えて ヌル文字を削除して下さい。 ・改行コードの取り除き方は、次の関連質問の回答者 No.3 や他の回答者さんの方法を 試して下さい。下の『参考URL』をどうぞ。 ・あと fclose 関数の位置が間違っています。fopen ブロック内に記述しましょう。 サンプル: int main( void ) { FILE *fp; char a[50]; char b[50]; if ( (fp = fopen("A.PRM", "r" )) != NULL ){ ←EOF ではなく NULL です。 if ( fgets(a,sizeof(a),fp) != NULL ){ ←sizeof演算子を使うと便利です。 /* 改行コードを取り除く処理 */ } if ( fgets(b,sizeof(b),fp) != NULL ){ ←sizeof演算子を使うと便利です。 /* 改行コードを取り除く処理 */ } fclose( fp ); ←この位置です。 } printf( "a = %s\n", a ); printf( "b = %s\n", b ); return( 0 ); } 最後に: ・fgets 関数も戻り値をチェックした方がいいですよ。 ・以上。おわり。
その他の回答 (2)
- nobe
- ベストアンサー率66% (59/89)
ANo.1 さんが適切な回答をされていますね。 きっと一発で改行文字を読まないようなコードが欲しいんだと 思いますが、改行が付いてしまうのはfgetsの仕様なので あきらめてください。 代りと言っては何ですが、 改行コードを取り除く関数を考えてみました。 char* trim(const char* buffer) { char *p = (char*)buffer, *q = p; while (*p && *p != '\n') p++; *p = 0; return q; } 漢字が入っていたらもうちょっと複雑ですが、 ASCII等の英数字記号だけならこれでいいと思います。 呼び出しは、 /* 改行コードを取り除く処理 */ trim(a); みたいな感じで呼び出せばよいかと。 ご参考までに。
お礼
大変遅くなりましたが、ご回答ありがとうございました。 どうもライブラリ関数によって一発解決しようと考えてしまうようです。自作関数なども考慮に入れ、ロジックを追求しようと思います。 コードの記述ありがとうございます。
- jacta
- ベストアンサー率26% (845/3158)
> fgetsの代わりにfscanfを使用すると、今度はスペースの前までしか読み込んでくれず、「a = I」「b = He」と表示されてしまいます。 それは書式指定が悪いからです。 fscanf(fp, "%49[^\n]%*c", a);とすれば解決できるはずです。もっとも、入力が50文字以上になった場合の対策を行うにはもう一工夫必要ですが、それはfgetsの場合でも同じです。
お礼
大変遅くなりましたが、ご回答ありがとうございました。 書式指定についてはまったく知りませんでした。この方法を試してみようと思います。
お礼
大変遅くなりましたが、ご回答ありがとうございました。 ご指摘いただいたミスは、自分では正しく記述したつもりでいました‥ 関数の仕様ももちろんですが、どうしたらその問題点を解決できるかをもっと自分で考え抜いた方が良いことに気づかせてくれた回答でした。 コード記述ありがとうございます。