- ベストアンサー
fgetsを使ってcsvからcsvに
csvファイルからfgetsを使い任意の文字列を取り出して新たなcsvファイルに出力したいのですがなかなかうまくいきません。ご指摘の方よろしくお願いします。 csvデータ 社名,住所,番号,設立年,従業員数,分類 山川商事,東京,123,8,60,証券 谷運輸,,578,20,400,運送 空海コンピュータ,,456,,300,ソフトウェア ・ ・ ・ データの3,5,6番目を取り出したい。(データが入ってない箇所もある) #include <stdio.h> int main(void) { FILE *fp1,*fp2; char data[256]; char *data_p = data; int cnt = 0; char ch[256]; char *ch_p = ch; //ファイルオープン(fp1)// //ファイルクローズ(fp2)// while (fgets(data, 255, fp1) != NULL) { if (*data_p != ',') { if(cnt == 2) { *ch_p = *data_p; data_p++; ch_p++; } if (cnt == 4) { *ch_p = *data_p; data_p++; ch_p++; } if (cnt == 5) { *ch_p = *data_p; data_p++; ch_p++; } } else { if (cnt == 2) { *ch_p = *data_p; data_p++; ch_p++; } if (cnt == 4) { *ch_p = *data_p; data_p++; ch_p++; } if (cnt == 5) { *ch_p = *data_p; data_p++; ch_p++; } cnt++; x++; } } y = '\0'; fprintf(fp2, "%s", ch); fclose(fp1); fclose(fp2); }
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
この問題は、元のCSVファイルから番号、設立年、従業員数を どのように抽出するか?がポイントであると思います。 fgets関数は改行までの1行をファイルから取得するので、 取得したカンマ区切りの文字列から必要なデータのみを抽出する必要があります。 私ならバッファをいくつか用意してこんな感じで実装します。 --- /* 入力元のファイルを開く */ /* 出力先のファイルを開く */ while( /* fgetsで文字列をファイルから取得 */ ) { /* fgetsで取得した1行(文字列A)をこのループで解体する */ for( int i = 0; i < 6; i++ ) { /* 文字列Aからカンマまでの文字列を取得して文字列Bへコピー【※1】 */ /* 文字列Aから取得した文字列を除去しておく【※2】 */ /* 何番目のデータなのかで処理を分岐させる */ switch( i ) { case 0: /* 社名 */ case 1: /* 住所 */ case 5: /* 分類 */ /* このデータは不必要なので何もしない */ break; case 2: /* 番号 */ case 3: /* 設立年 */ case 4: /* 従業員数 */ /* 必要なデータなので文字列Bをファイルに出力する【※3】 */ break; } } /* 出力先を改行する */ } /* 入力元のファイルを閉じる */ /* 出力先のファイルを閉じる */ --- ポイントは【※1】と【※2】と【※3】です。 【※1】は文字列の中からカンマを検索し、 カンマまでのデータを別の配列にコピーします。 『分類』の末尾にはカンマが無いので注意が必要です。 【※2】はループによって※1が再び処理された時に、取得済みの データを再処理しない為に、対象の文字列から除去しておく 必要があります。 1回目 『AAA,BBB,CCC,DDD,EEE,FFF』から『AAA』を取り出す 2回目 『BBB,CCC,DDD,EEE,FFF』から『BBB』を取り出す 3回目 『CCC,DDD,EEE,FFF』から『CCC』を取り出す (以下、末端まで続く) つまり2回目の処理を開始する時には『AAA』を取り除いておく訳です。 【※3】は従業員数にはカンマが不必要なのでちょっと工夫する必要があります。 こんな感じでどうでしょう?
その他の回答 (1)
- seta_takahiro
- ベストアンサー率60% (23/38)
x++というのとy='\0'というのがよくわかりませんでしたが、 気づいた分だけ whileの内側にもう一段whileが必要なのではないか while(*data_p != '\0'){} 的なものを入れないと、 読み込んだ255バイトの最初の1文字しか読まないということはないか ch_p++の方はchに書き出したときのみで良いと思うが、 data_p++ は、chに書き出したかどうかにかかわらず 行う必要があるのではないか? 外側のwhile(今あるfgetsのwhile)の最初で data_p = data; ch_p=ch; で初期化する必要があるのではないか? 外側のwhileの中の最後で *ch_p='\0';とfprintf(fp2, "%s", ch); とを行う必要があるのではないか? fcloseはwhileの外で行うのではないか? cntの初期値は0ではなく1なのではないか?
お礼
細かな指摘ありがとうございました。 参考にさせていただきます。
お礼
なるほど、こういったコーディングもあるのですね。 参考にさせてもらいます。