- ベストアンサー
C言語についてアドバイスをください。
CSVファイルの内容をfreadで読み込み、strtokを使わずにbuffに格納した後、 buffから1文字ずつbuff2へコピーさせていって、コンマがきたら数字、 改行がきたら名前と判別して、自作関数に渡して表示させたいです。 CSVファイルの内容は 『11,名前1(改行) 15,名前2(改行) 18,名前3』 といった感じです。 ------------------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE 1 #include <stdio.h> #include <string.h> #include <stdlib.h> #define NUM 256 struct kou { short nenrei; char namae[30]; }; void pri(struct kou *o) { printf("%d\n%s\n",o->nenrei,o->namae); } int main(void) { FILE *fp; // ファイルポインタ char buff1[NUM] = {0}; char buff2[NUM] = {0}; char *fname = "text1.csv"; // ファイル名を指定 short i = 0; int n = 0; struct kou p; fp = fopen(fname, "r"); if(fp == NULL) { printf("%sファイルをオープンできませんでした。\n",fname); } fread(buff, 1, NUM, fp); while(buff1[n] != NULL) { buff2[n] = buff1[n]; // buff2[0]からbuff1の中を一文字ずつコピーしていく。 if(buff2[n] == ',') // buff2に格納されていく中にコンマがきたら以下の作業を行う。 { i = (short)atoi(buff2); // char型からshort型への変換 p.nenrei = i; } if(buff2[n] == '\n') { strcpy(p.namae,buff2); // p.namaeにbuff2をコピー。 pri(&p); } n++; } fclose(fp); printf("ファイルをクローズしました。\n"); return 0; } ------------------------------------------------------- 今のままだと 『11 11,名前1 11 11,名前1 15,名前2』 という表示になってしまいます。 while 内で既に読み込んだ部分を読み込ませないよう(表示させないよう)にできたら良いと思うんですが、そういったやり方はあるのでしょうか? むしろやり方を変えたほうが良いでしょうか・・・。 まだC言語を学び始めて日が浅いので、色々間違っている部分もあると思いますが、 そういったことを含めてアドバイスをいただけたらと思います。 よろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
以下の部分が要求仕様を満たしているのか確認しましょう int main(void) { FILE *fp; // ファイルポインタ char buff1[NUM] = {0}; char buff2[NUM] = {0}; char *fname = "text1.csv"; // ファイル名を指定 short i = 0; int n = 0; struct kou p; fp = fopen(fname, "r"); if(fp == NULL) { printf("%sファイルをオープンできませんでした。\n",fname); } fread(buff, 1, NUM, fp); // 読み込みが成功したのかチェックしなくてもいいのか while(buff1[n] != NULL) { buff2[n] = buff1[n]; // buff2[0]からbuff1の中を一文字ずつコピーしていく。 if(buff2[n] == ',') // buff2に格納されていく中にコンマがきたら以下の作業を行う。 { i = (short)atoi(buff2); // char型からshort型への変換 p.nenrei = i; // カンマを処理したので次に取り込むbuf2への書き込み位置を // 変更しなくてもいいのか } if(buff2[n] == '\n') { // buf2先頭から構造体のメンバーにコピーするのなら // buf1/buf2にアクセスする変数nは1つで出来るのか // この記述だと構造体のnameに"\n"が付加されるが // これは意図した動作か strcpy(p.namae,buff2); // p.namaeにbuff2をコピー。 pri(&p); } n++; } fclose(fp); printf("ファイルをクローズしました。\n"); return 0; }
その他の回答 (2)
- asuncion
- ベストアンサー率33% (2127/6289)
#2です。 >pri(&p); pri関数の仕様から見て、ポインタを渡す必然性はないです。
お礼
補足回答をありがとうございます。
- asuncion
- ベストアンサー率33% (2127/6289)
>if(fp == NULL) ファイルが存在しない、などの理由でオープンできなかったときも 強引に読み込もうとしていますね。まずいです。 >fread(buff, 1, NUM, fp); 1行ずつ読み込むのでしたら、freadよりもfgetsあたりの方が使いやすいと思います。 ところで、buffという変数は定義していません。 >while(buff1[n] != NULL) NULLはポインタです。buff1[n]というchar型と比較することは正しくありません。 >i = (short)atoi(buff2); // char型からshort型への変換 >p.nenrei = i; iという中間的な変数を設ける必要はありません。 p.nenrei = atoi(buff2); でじゅうぶんです。 まずは、fgetsの使い方を調べてみてはいかがでしょうか。
お礼
丁寧な回答をありがとうございます。 やっぱりか~という部分とそうなのか!という部分がありました。 しっかり読んで理解を深めようと思います。
お礼
丁寧な回答をありがとうございます。 しっかり読んで理解を深めようと思います。