前提・実現したいこと
C言語初心者です。
fgetsを使って、txtファイルから文字列の配列を作りたいのですが、配列の中身の確認の仕方が分かりません。
以下のコードでbuf = "A, B, C, D"
のようになっているでしょうか?
またそれの確認方法をご教授ください。
sample.txtは以下のようになっています。
sample.txt
A
B
C
D
該当のソースコード
C
1#include <stdio.h> 2 3int main(void) 4{ 5 6 FILE *fp; 7 char buf[50]; 8 9 fp = fopen("sample.txt","r"); 10 11 while(fgets(buf,30,fp) != NULL){ 12 } 13 14 fclose(fp); 15 16 17 18 return 0; 19}
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
fgetsを使って、txtファイルから文字列の配列を作りたいのですが、配列の中身の確認の仕方が分かりません。
配列というのは char buf[50]; と宣言した buf ですね。
fgets の後は、読み込んだ文字列が入っているわけですから、
printf("[%s]\n", buf); で確認できます。
以下のコードでbuf = "A, B, C, D" のようになっているでしょうか?
なっていません。
fgets で読み込んだ文字列から最後の '\n' (改行文字) を取り除いて、
その文字列を ", " (コンマとスペース) でつないたものにしたいのですよね。
次のコードが理解できますか?
疑問点をコメントしてください。
C
1#include <stdio.h> // fopen, fclose, fgets, printf 2#include <string.h> // strlen 3 4#define N 50 5 6int main(void) 7{ 8 char buf[N]; 9 int i = 0; // buf への読み込み位置 10 11 FILE *fp = fopen("sample.txt","r"); 12 if (fp == NULL) return 1; 13 14 while (fgets(buf + i, N - i, fp) != NULL) { 15 i += strlen(buf + i) + 1; 16 buf[i-2] = ','; 17 buf[i-1] = ' '; 18 } 19 buf[i-2] = '\0'; 20 fclose(fp); 21 22 printf("[%s]\n", buf); 23}
入力が多すぎてバッファオーバーランしないように
while (fgets(buf + i, N - i, fp) != NULL) {
は
while (i < N - 20 && fgets(buf + i, N - i, fp) != NULL) {
のように制限したほうが良いでしょう。
投稿2020/11/01 13:28
編集2020/11/01 13:32総合スコア8224
0
配列bufは質問で書かれている意図通りの結果にはなりません。
配列bufの中身はfgetを呼ぶたびに上書きされるので、「A,B,C,D」のような文字列を得たいのだとしたらbufに読みこんだ後に別の文字配列へコピーしていくような処理が必要だと思います。
ソースコードにprintf()を入れてあげれば手っ取り早く確認できると思います。
C
1#include <stdio.h> 2 3int main(void) 4{ 5 6 FILE *fp; 7 char buf[50]; 8 9 fp = fopen("sample.txt","r"); 10 11 while(fgets(buf,30,fp) != NULL){ 12 13 printf( "buf=(%s)\n", buf ); 14 } 15 16 fclose(fp); 17 18 printf( "loop end\n" ); 19 printf( "buf=(%s)\n", buf ); 20 21 return 0; 22}
terminal
1$ ./hoge 2buf=(A 3) 4buf=(B 5) 6buf=(C 7) 8buf=(D 9) 10loop end 11buf=(D 12)
#コメントを受けて追記
sampleという文字列配列に格納する処理の一例を書いてみました。
printf()で途中経過を表示するようにしてみたので確認してみてください。
C
1#include <stdio.h> 2#include <errno.h> 3#include <string.h> 4 5int main(void) 6{ 7 8 FILE *fp; 9 char buf[50]; /* 制限: 入力ファイルの1行の長さは49文字以外でなければならない */ 10 char sample[1024]; /* 制限: 最終的な結果文字列のサイズは1023文字に収まらなければならない */ 11 12 fp = fopen("sample.txt","r"); 13 if ( fp == NULL ) { 14 perror( "fopen" ); 15 return 1; 16 } 17 18 /* sampleを文字列長が0の文字列となるように初期化する */ 19 sample[0] = '\0'; 20 21 while(fgets(buf,sizeof(buf),fp) != NULL){ 22 23 printf( "buf(before)=(%s)\n", buf ); 24 25 /* 行末の改行文字をカンマに置き換える */ 26 buf[ strlen( buf ) - 1 ] = ','; 27 28 printf( "buf(after)=(%s)\n", buf ); 29 30 /* sampleの末尾に現在のbufを連結する */ 31 strcat( sample, buf ); 32 33 printf( "sample=(%s)\n", sample ); 34 35 printf( "\n" ); 36 } 37 38 fclose(fp); 39 40 /* sampleの末尾にあるカンマを削除する */ 41 sample[ strlen( sample ) - 1 ] = '\0'; 42 43 printf( "loop end\n" ); 44 printf( "sample=(%s)\n", sample ); 45 46 return 0; 47}
terminal
1$ ./hoge 2buf(before)=(A 3) 4buf(after)=(A,) 5sample=(A,) 6 7buf(before)=(B 8) 9buf(after)=(B,) 10sample=(A,B,) 11 12buf(before)=(C 13) 14buf(after)=(C,) 15sample=(A,B,C,) 16 17buf(before)=(D 18) 19buf(after)=(D,) 20sample=(A,B,C,D,) 21 22loop end 23sample=(A,B,C,D)
投稿2020/10/31 14:27
編集2020/11/01 09:49総合スコア1248
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/01 07:17
2020/11/01 08:48
2020/11/01 09:45
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。