No.5ベストアンサー
- 回答日時:
>mallocで取れるだけ領域を取ってそこからその
処理系や環境によりますがWindowsやLinuxの場合100Mぐらいは余裕でとれてしまいます。
>構造体の途中からfreadすることって可能でしょうか?
可能です。
memcpy( (char*)s+読み込んだバイト , pBuf , structSize - (読み込んだバイト) );
みたいな感じになります。
sizeを読み込んでから切れる場合と、sizeの前で切れる場合があるので
sizeの前で切れた場合は次のバッファを読み込んでから構造体のサイズを確定する処理
をする必要があるでしょう。
ただ構造体のalignmentには注意してください。
例えば
typedef struct _S{
char a;
short b;
}S;
の場合3バイトとは限りません。コンパイラの設定によっては
paddingの部分で切れる可能性も考慮する必要があります。
No.7
- 回答日時:
実装例: #3のソースを改良したバージョン(解説は省略します、実際のテストは行っていません)
/* 1つの可変長・構造体データの最大バイト数(最低でも構造体サイズ+文字配列サイズ以上) */
#define MAX_SIZE (1024 * 1024) ←可能な限り大きいサイズで読み込む回数を減らせます
/* 可変長構造体のファイルからcsv形式のファイルへ出力 */
void FuncRead( FILE *fp, FILE *fo )
{
size_t size; /* 読み込んだバイト数 */
char *buff; /* 読み込むバッファ領域(先頭位置) */
char *last; /* 読み込むバッファ領域(最終位置) */
char *seek; /* 参照したバッファ位置(現在位置) */
構造体(仮) *data; /* 参照する構造体へのポインタ */
if ( (buff = malloc(MAX_SIZE)) != NULL ){
while ( (size = fread(buff,1,MAX_SIZE,fp)) != 0 ){
last = (buff + size);
seek = (buff);
data = (構造体(仮) *)seek;
while ( (data->str + data->size - 1) < last ){
FuncWrite( data, fo ); ←構造体(仮)のデータを出力させる関数
seek += (sizeof(構造体(仮)) + data->size - 1);
data = (構造体(仮) *)seek;
}
if ( feof(fp) ){
break;
}
fseek( fp, -(size_t)(last - seek), SEEK_CUR ); ←ファイルポインタを戻る
}
free( buff );
}
}
/*
●引数
(1)入力ファイルのポインタを fp で指定
(2)出力ファイルのポインタを fo で指定
●その他
void FuncWrite( 構造体(仮) *data, FILE fo );
●注意
・1つの可変長・構造体データは、構造体サイズ+data->size-1ですよ。
・文字配列が文字列ならば、NULL文字分を考えて上記ソースの-1は削除しましょう。
*/
改良版ありがとうございます。
とりあえず内容を見てみました。
このソースの処理は、
> while ( (data->str + data->size - 1) < last ){
> fseek( fp, -(size_t)(last - seek), SEEK_CUR ); ←ファイルポインタを戻る
のところを見る限り構造体全体が読めなかったら
ファイルポインタを読めなかった構造体の最初に戻って読み直すという
処理をしているみたいですね。
構造体の途中から読むということもしないので無難かもしれませんね。
No.6
- 回答日時:
#5です。
追記です。例えば1024バイトのバッファで何回も読み込んでいくような方式を考えた場合に
構造体のsizeが5000バイトを超えるようなパターンもありますね。
この回答への補足
あ、多分これは大丈夫です。
10Mぐらいのバッファで構造体もバッファより大きいものは存在しない予定なので・・・
それとついでの質問なのですが、
mallocで取れるバッファのサイズを調べる関数とかあるのでしょうか?
No.3
- 回答日時:
最初にftellでファイルサイズを取得しmallocで領域を確保し
freadで全部メモリーに読み込めばいいのでは?
そうすれな読み込み回数は1回で済みますから。
ファイルサイズが大きくmallocで確保できないような連続領域が必要なら
無理ですが。
簡単に書くとこんなかんじでしょうか。(なんのエラー処理もしていません)
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct _STRUCT
{
char c1,c2;
float f1,f2;
double d;
int size;
char str[1];
}STRUCT;
int main()
{
size_t structSize;
STRUCT* s;
char* pBuf;
size_t FileSize;
size_t ReadSize = 0;
FILE* fp = fopen("hoge.dat","rb");
fseek(fp,0,SEEK_END);
FileSize = ftell(fp);
printf("FileSize=%u\n",FileSize);
fseek(fp,0,SEEK_SET);
pBuf = (char*)malloc(FileSize);
fread(pBuf,FileSize,1,fp);
fclose(fp);
while( ReadSize < FileSize ){
structSize = sizeof(STRUCT) - sizeof(char) + ((STRUCT*)pBuf)->size;
s = (STRUCT*)malloc(structSize);
memcpy( s , pBuf , structSize );
printf("%s\n",s->str);
free( s );
ReadSize += structSize;
pBuf+=structSize;
}
free(pBuf);
}
この回答への補足
ありがとうです。
自分のしたかったことに近いです。
ですがファイルサイズがでかくなることも想定しているので
mallocで取れるだけ領域を取ってそこからその処理をして、
領域の最後に達したらファイルから読み直すという処理をつけたいと思ってます。
ですがそうした場合、構造体の途中までしか読めていない状況が発生すると思っています。
その場合欠けた部分より後はfreadで読み込む処理を入れなくてはいけない気がします。
ですが構造体の途中からfreadすることって可能でしょうか?
No.2
- 回答日時:
typedef struct 構造体(仮) {
char c1, c2;
float f1, f2;
double d;
int size;
chear str[1];
} 構造体(仮);
の形だと (構造体タグって必要?), 実際に使うにはこの構造体に対して malloc しないといけないんだけどその辺は OK? まあいいとして, 基本的には
0.仮にデータを保存しておく構造体を用意する
1.size まで fread
2.その size に従って構造体を malloc する
3.size のところまで memcpy
4,size の分だけ fread
の順. 今の ISO C なら str を
char str[];
で宣言できて, この場合には
{
構造体(仮) dummy, *data;
fread(&dummy, sizeof dummy, 1, fp);
data = malloc(sizeof *data + dummy.size);
memcpy(&dummy, data, sizeof dummy);
fread(data->str, 1, data->size, fp);
}
くらいになるかと.
1の方の方法をソースで書いてくれたのですね。
ありがとうです。
・・・ですが1の方のところで書いたとおりその方法は考えてはいました。
もう少し詳しく書いておくべきでしたね、すみません。
No.1
- 回答日時:
私だったら、
void hoge( int fd ) {
構造体(仮) kari;
int sz, cc;
char *str;
sz = (int) ( (void*) &kari - (void*) &kari.str );
cc = read( fd, &kari, sz );
/* cc をチェック */
str = (char*) malloc( kari.size );
/* str をチェック */
cc = read( fd, str, kari.size );
/* cc をチェック */
}
てな感じでしょうか。要は構造体(仮)のsizeまで最初に読みこんでから、size を見て、文字列を読むだけです。
ファイルを読み込む回数ですが、Linux とか最近のOSではメモリにキャッシュされるので、回数は昔ほど気にしなくても大丈夫です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
char*を初期化したいのですが
-
CStringからchar*への型変換に...
-
C言語のintとcharの違いってな...
-
DWORDとcharの変換
-
char 文字列型 の表現範囲が-12...
-
文字列内の数字削除
-
警告 : 問題のあるポインタの変換
-
C++17で、unsigned char * 配列...
-
文字列str内の全ての数字を...
-
csvファイルをfscanfで読み込む...
-
C++Builder 2009 テキスト...
-
new charとnew char[N]の違いは?
-
2次元配列の文字"列"の初期化方法
-
C言語にて構造体のメンバがNULL...
-
文字の代入とコピーについて
-
しつこい様ですが、再度ポイン...
-
ポインタを使って回文かどうか...
-
ASCIIコードへの変換方法
-
小数点入りの文字列をfloat型に...
-
C言語を用いた環境変数の作成/...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語のintとcharの違いってな...
-
CStringからchar*への型変換に...
-
char*を初期化したいのですが
-
C言語にて構造体のメンバがNULL...
-
fstream型オブジェクトを関数の...
-
小数点入りの文字列をfloat型に...
-
new charとnew char[N]の違いは?
-
DWORDとcharの変換
-
char型にint型の数値を代入する。
-
C言語のプログラムについてです
-
2次元配列の文字"列"の初期化方法
-
文字型配列に格納した空白の切捨て
-
C++17で、unsigned char * 配列...
-
char 文字列型 の表現範囲が-12...
-
文字列の途中から途中までを抽出
-
警告
-
C言語 strstrの実装
-
コマンドライン引数 *argv[]は...
-
csvファイルをfscanfで読み込む...
-
C言語の文字リテラル中の16進文...
おすすめ情報