![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
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;
}
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_14.png?e8efa67)
No.3ベストアンサー
- 回答日時:
#2方が適切なアドバイスをされていますので、
そのアドバイスに従い、書き換えると以下のようになります。
char data;として
while (1)
{
if(fscanf(FPi,"%x" , &getdt) == EOF )
{break; }
data = getdata;
fwrite(&data, sizeof(data), 1, FPo);
}
要は、1回のfscanfで1文字が取得できるので、それを直ちに書き込みます。これを、入力ファイルがからになるまで繰り返します。そうすれば、入力ファイルのサイズが、いくら大きくても大丈夫です。
No.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関数の戻り値は書き込んだ要素数です。
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_04.png?e8efa67)
No.1
- 回答日時:
data[]という配列サイズを固定にしているため、5Mバイト超えるとオーバーフローしますね。
配列に溜め込む方式を辞めて、1ブロック読み込んだら1ブロック書き出すというようにしましょう。
(ブロックサイズは扱うファイルサイズによって調整すればパフォーマンスを上げることができますが、たとえば1024バイトではいかがでしょう。)
この回答への補足
早速のアドバイス有難うございます。
ご指摘の通り、"1ブロック読み込んだら1ブロック書きだす"としたいのですが、fwriteの使い方が根本的に分かってないものですから、このようなお粗末な状況となっております。
どうしたら実現できますか?
尚、data[]の中の固定値はいろいろ変えてみたのですが上記あるように7M超えるとCoreダンプします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・「I love you」 をかっこよく翻訳してみてください
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・昔のあなたへのアドバイス
- ・かっこよく答えてください!!
- ・あなたが好きな本屋さんを教えてください
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・【大喜利】【投稿~8/27】 こんなガソリンスタンド二度と来るか!なぜそう思った?
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・【お題】動物のキャッチフレーズ
- ・【お題】甲子園での思い出の残し方
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・自分用のお土産
- ・人生で一番お金がなかったとき
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・ちょっと先の未来クイズ第1問
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
define で 配列
-
ポインタを使って構造体の配列...
-
c言語
-
Cのエラー
-
[C++]const int と配列
-
C言語において、 配列要素をひ...
-
C#で構造体の配列を持った構造...
-
VB.NETにおける構造体の初期化
-
C++DLLからC#へのコールバック...
-
C#でのフィボナッチ数列
-
AfxBeginThread の引数について
-
C#で配列が空かを判定するには?
-
fscanfについて質問です。
-
バイナリデータ作成したいので...
-
構造体のextern方法
-
配列のアドレス部
-
int i, int i[1];
-
MFCのCArrayを使った二次元配列
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数から配列を返すには?
-
構造体のextern方法
-
配列の要素数に変数を入れたい...
-
C言語において、 配列要素をひ...
-
define で 配列
-
c言語
-
C#で構造体の配列を持った構造...
-
C言語 ファイルの指定された行...
-
c言語 構造体
-
コンボボックスでデフォルト値...
-
配列のアドレス部
-
MFCのCArrayを使った二次元配列
-
MFC - ダイアログボックスのPic...
-
C言語についてです 5人のテスト...
-
C言語から質問です。
-
AfxBeginThread の引数について
-
C言語の課題が出たのですが自力...
-
Cのエラー
-
int i, int i[1];
-
C#で配列が空かを判定するには?
おすすめ情報