No.16242![]() |
バイナリファイル読み込み 投稿者---AI(2004/08/19 11:31:48) |
||
お世話になります。AIです。 今バイナリファイルについて学習しています。 ftell()で求めるレコード数とはどう言う意味なのでしょうか? また、fread()の引数のデータサイズでバイナリファイル全てのデータを読み込むことができるのでしょうか? よろしくお願いします。 |
No.16243![]() |
Re:バイナリファイル読み込み 投稿者---Sciggepy(2004/08/19 12:16:48) |
||
>ftell()で求めるレコード数とはどう言う意味なのでしょうか? ftellが返す値は、ファイル内のその時点での読み取り位置です。バイナリファイルでは、先頭からのバイト数が返ります。 >また、fread()の引数のデータサイズでバイナリファイル全てのデータを読み込むことができるのでしょうか? freadは実際に読み取った要素の数を返します。 fread(buf,1,n,pf); は、nバイトのデータをpfが示すファイルから読み取り、bufに格納しますが、nよりも少ない値が返されたときは、ファイルの最後に達したと判断してよいでしょう。(エラーの場合もあります。) |
No.16244![]() |
Re:バイナリファイル読み込み 投稿者---AI(2004/08/19 13:34:02) |
||
バイナリファイルを全て読み込みたい場合は どのようにしたらよいのでしょうか? while分でファイルの最後までと指定するのでしょうか? よろしくお願いします。 |
No.16245![]() |
Re:バイナリファイル読み込み 投稿者---AI(2004/08/19 13:55:17) |
||
>バイナリファイルを全て読み込みたい場合は >どのようにしたらよいのでしょうか? >while分でファイルの最後までと指定するのでしょうか? >よろしくお願いします。 ファイルの文字列を配列に格納したいです。 読み込むファイルは、NULL文字が付加 されているので、fgetsでは無理なのではないかと 考えています。 EOFまで読むことを指定すると 読み込めるのでしょうか? |
No.16246![]() |
Re:バイナリファイル読み込み 投稿者---Sciggepy(2004/08/19 15:30:47) |
||
ファイルをすべて読み込む場合は、次のようにします。 #include <stdio.h> #define BYTESRD 1024 size_t readfile(FILE *pf,void **ppb) { char *buf,*nbuf; size_t s,p=0; buf=(char *)malloc(BYTESRD); if(!buf) return (size_t)-1; while((s=fread(buf+p,1,BYTESRD,pf))==BYTESRD) { s=0; p+=BYTESRD; nbuf=(char *)realloc(buf,p+BYTESRD); if(!nbuf) break; buf=nbuf; } *ppb=(void *)buf; return p+s; } int main(int argc,char **argv) { FILE *pf; char *buf; size_t s; if(argc<3) return 0; pf=fopen(argv[1],"rb"); s=readfile(pf,(void **)&buf); fclose(pf); pf=fopen(argv[2],"wb"); fwrite(buf,1,s,pf); fclose(pf); free(buf); printf("%d\n",s); return 0; }読み込みエラーの判定はしていません。(できない?) 一度ですべてのデータを読み込むには、低水準入出力など、環境依存のコードを書く必要があります。 |
No.16247![]() |
Re:バイナリファイル読み込み 投稿者---かずま(2004/08/19 17:32:54) |
||
> ファイルをすべて読み込む場合は、次のようにします。 ちょうど 1KB のファイルを読み込むとき、2KB のメモリを確保しますね。 realloc は、メモリのコピーを伴う場合があります。 大量のデータに対して、realloc を頻繁に呼び出すのは効率が悪くないですか? > 一度ですべてのデータを読み込むには、低水準入出力など、環境依存の > コードを書く必要があります。 次のプログラムは、一度ですべてのデータを読み込んでいますが、 どの部分が環境依存でしょうか? #include <stdio.h> #include <stdlib.h> void dump(void *buf, int size) { unsigned char *p = buf; int i = 0; while (i < size) { printf(" %02x", p[i]); if ((++i & 15) == 0) printf("\n"); } if (i & 15) printf("\n"); } int main(int argc, char *argv[]) { FILE *fp; long size, n; char *buf; if (argc != 2) return 1; fp = fopen(argv[1], "rb"); if (fp == NULL) return 1; fseek(fp, 0, SEEK_END); size = ftell(fp); printf("size=%ld\n", size); buf = malloc(size); if (buf == NULL) return 1; rewind(fp); n = fread(buf, 1, size, fp); if (n > 256) n = 256; dump(buf, n); return 0; } |
No.16248![]() |
Re:バイナリファイル読み込み 投稿者---Ban(2004/08/19 18:02:25) |
||
> fread(buf, 1, size, fp); 元質問の「ftell()で求めるレコード数」あたりから推測するに、 byte 単位での読み出しではなく、固定レコード長のバイナリを前提に ftell のオフセットからレコード数を算出し、それを引数に fread することを想定した問題な気もします。 |
No.16249![]() |
Re:バイナリファイル読み込み 投稿者---Sciggepy(2004/08/19 18:35:20) |
||
毎度ご指摘ありがとうございます。 > fseek(fp, 0, SEEK_END); > size = ftell(fp); その手がありましたね。 APIばかり使っているので、すっかり忘れていました。 #私のCの知識は、本を買って勉強したわけでもなく、 #誰かに教えてもらったということもないので、基本的に穴だらけです。 #標準Cでまともなプログラムを書いたことは、数えるほどもありません。 #fseekやftellに関しては、使ったこともありませんでした。 |
No.16317![]() |
Re:バイナリファイル読み込み 投稿者---AI(2004/08/23 19:06:08) |
||
返答ありがとうございます。 追加ですが、 テキストファイルで文字列処理を行う場合、 例えば、あるテキストファイルデータを配列に格納し、 その配列で、検索文字で検索をして文字を分離させることは strchr()などでできますが、 バイナリファイルにおいて、そのようなことは出来るのでしょうか? 文字列処理において、テキストファイルで行っていた処理が バイナリファイルになるとこのように変わるなど、 何かあれば教えていただければ助かります。 よろしくお願いします。 |
No.16318![]() |
Re:バイナリファイル読み込み 投稿者---REE(2004/08/23 20:10:24) |
||
まず、テキストファイル/バイナリファイルの処理と 文字列・バイナリデータ処理は別の物として考えるようにして下さい。 ここでは、文字列とバイナリデータの違いを考えて見ます。 文字列とバイナリデータの一番の違いはヌル文字の扱いです。 文字列:必ず'\0'で終わる。 バイナリデータ:'\0'を特別視しない、そのためデータだけでは長さが分からない。 そのため、通常は同じ関数での処理は出来ません。 ライブラリ関数も、strで始まる文字列用と、memで始まるバイナリデータ用に分かれています。 |