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

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関数の戻り値は書き込んだ要素数です。

No.1
- 回答日時:
data[]という配列サイズを固定にしているため、5Mバイト超えるとオーバーフローしますね。
配列に溜め込む方式を辞めて、1ブロック読み込んだら1ブロック書き出すというようにしましょう。
(ブロックサイズは扱うファイルサイズによって調整すればパフォーマンスを上げることができますが、たとえば1024バイトではいかがでしょう。)
この回答への補足
早速のアドバイス有難うございます。
ご指摘の通り、"1ブロック読み込んだら1ブロック書きだす"としたいのですが、fwriteの使い方が根本的に分かってないものですから、このようなお粗末な状況となっております。
どうしたら実現できますか?
尚、data[]の中の固定値はいろいろ変えてみたのですが上記あるように7M超えるとCoreダンプします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# #include <stdio.h>int main(void) { int buf[100] = 6 2022/11/01 22:45
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
配列の要素数に変数を入れたい...
-
c言語
-
関数から配列を返すには?
-
C#で構造体の配列を持った構造...
-
ポインタのアドレスについて
-
callocで二次元配列を作成する...
-
メモリ上に配置されていないバ...
-
エラー:浮動小数点の不正な使用
-
ファイルから読み込み、配列
-
DxlibのLoadgraph()を使ったsta...
-
行きがけ順で表示するプログラム
-
配列とポインタでの書き直し(...
-
このプログラム見てもらえますか?
-
define で 配列
-
2次元配列のマスを数える方法...
-
2番目の最大値を求める
-
C言語 動的確保とポインタ参照...
-
配列のアドレス部
-
ループカウンタを使用せず、配...
-
C言語(サイズ指定のない配列)
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
define で 配列
-
C#で構造体の配列を持った構造...
-
コンボボックスでデフォルト値...
-
C#で配列が空かを判定するには?
-
MFC - ダイアログボックスのPic...
-
構造体のextern方法
-
C言語において、 配列要素をひ...
-
C言語の2次元配列 容量が大き...
-
配列のアドレス部
-
配列の配列をmemcpyやmemcmpし...
-
万年カレンダーについて。
-
C言語 ファイルの指定された行...
-
この変数名はわかりにくいですか?
-
MFCのCArrayを使った二次元配列
-
fclose()でセグメンテーション違反
-
c言語
-
C言語の配列のコピーについて
-
マルチスレッド環境での配列使...
おすすめ情報