- ベストアンサー
バイナリデータ作成したいのですが、fwriteの使用方法を教えてください。
indataというhexで書かれたテキストファイルをバイナリデータに変換したく 以下のようなプログラムを作成しましたが、dataのサイズを大きくすると coreダンプしてしまいます。具体的には7M超くらいから。 入力ファイルサイズはほぼ無限にあり、出力バイナリファイルは20MByteは欲しいです。 どのように改造したら、大きなサイズのバイナリファイルが作成できるでしょうか? 初心者ながら、いろいろ調べてここまで作成したので、根本がおかしいかもしれません。 よろしくお願いいたします。 #include<stdio.h> int main(void) { FILE *FPi, *FPo; char data[5000000]; int getdt,x; FPi=fopen("indata","r"); if ( FPi == NULL ) {return 1;} FPo = fopen("res.bin","wb"); if ( FPo == NULL ) {return 1;} x=0; while (1) { if(fscanf(FPi,"%x" , &getdt) == EOF ) {break; } data[x]=getdt; x++; } fwrite(data, sizeof(data), 1, FPo); fclose(FPo); fclose(FPi); return 0; }
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#2方が適切なアドバイスをされていますので、 そのアドバイスに従い、書き換えると以下のようになります。 char data;として while (1) { if(fscanf(FPi,"%x" , &getdt) == EOF ) {break; } data = getdata; fwrite(&data, sizeof(data), 1, FPo); } 要は、1回のfscanfで1文字が取得できるので、それを直ちに書き込みます。これを、入力ファイルがからになるまで繰り返します。そうすれば、入力ファイルのサイズが、いくら大きくても大丈夫です。
その他の回答 (2)
まず、コアダンプの理由から。 dataの宣言がauto(自動変数)になっています。 これではアプリケーションのスタック領域をすぐに使い果たしてしまいます。 このような大きな配列を宣言するときは、static属性をつけます。 static char data[5000000]; (もし動的メモリ割り当てを御存じなら、 配列のかわりにそれを使いましょう。 その場合sizeof(data);などとは出来ないことには 注意してください。) 次にfwrite関数の使いかたですが、 fwrite関数の定義は size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream); となっています。 ptrには書き込むデータへのポインタをあたえます。 第2引数のsizeには1要素あたりの大きさをあたえます。 例えば、書き込む単位が配列全体であれば、 sizeof(data)、int型の整数ならsizeof(int)とします。 第3引数のnには、書き込む要素数をあたえます。 第2引数に指定したサイズのものが幾つ続いているか、という値です。 最後の引数streamには、fopenの戻り値をあたえます。 というわけで、ご質問のソースでは使いかたはあっています。 配列をやめて1バイトずつ、例えばchar c;と宣言されたcを書き込むのなら、 fwrite(&c, sizeof(c), 1, FPo); とするわけです。 ただ、これを5000000回ループするのは止めたほうがいいと思いますが。 因みにfwrite関数の戻り値は書き込んだ要素数です。
お礼
大変有難うございました。
- 50100
- ベストアンサー率28% (99/351)
data[]という配列サイズを固定にしているため、5Mバイト超えるとオーバーフローしますね。 配列に溜め込む方式を辞めて、1ブロック読み込んだら1ブロック書き出すというようにしましょう。 (ブロックサイズは扱うファイルサイズによって調整すればパフォーマンスを上げることができますが、たとえば1024バイトではいかがでしょう。)
補足
早速のアドバイス有難うございます。 ご指摘の通り、"1ブロック読み込んだら1ブロック書きだす"としたいのですが、fwriteの使い方が根本的に分かってないものですから、このようなお粗末な状況となっております。 どうしたら実現できますか? 尚、data[]の中の固定値はいろいろ変えてみたのですが上記あるように7M超えるとCoreダンプします。
お礼
大変有難うございました。 教えていただいた方法で解決いたしました。