泣きながら食べたご飯の思い出

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;
}

A 回答 (3件)

#2方が適切なアドバイスをされていますので、


そのアドバイスに従い、書き換えると以下のようになります。
char data;として
while (1)
{
if(fscanf(FPi,"%x" , &getdt) == EOF )
{break; }
data = getdata;
fwrite(&data, sizeof(data), 1, FPo);
}
要は、1回のfscanfで1文字が取得できるので、それを直ちに書き込みます。これを、入力ファイルがからになるまで繰り返します。そうすれば、入力ファイルのサイズが、いくら大きくても大丈夫です。
    • good
    • 0
この回答へのお礼

大変有難うございました。
教えていただいた方法で解決いたしました。

お礼日時:2005/07/20 14:43

まず、コアダンプの理由から。


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関数の戻り値は書き込んだ要素数です。
    • good
    • 0
この回答へのお礼

大変有難うございました。

お礼日時:2005/07/20 14:43

data[]という配列サイズを固定にしているため、5Mバイト超えるとオーバーフローしますね。


配列に溜め込む方式を辞めて、1ブロック読み込んだら1ブロック書き出すというようにしましょう。
(ブロックサイズは扱うファイルサイズによって調整すればパフォーマンスを上げることができますが、たとえば1024バイトではいかがでしょう。)

この回答への補足

早速のアドバイス有難うございます。
ご指摘の通り、"1ブロック読み込んだら1ブロック書きだす"としたいのですが、fwriteの使い方が根本的に分かってないものですから、このようなお粗末な状況となっております。
どうしたら実現できますか?

尚、data[]の中の固定値はいろいろ変えてみたのですが上記あるように7M超えるとCoreダンプします。

補足日時:2005/07/19 19:58
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!