• 締切済み

ファイルポインタfpを、何バイト読んだかカウンタとして使うには?

ファイルポインタfpを、何バイト読んだかカウンタとして使うには?どうしたら良いか教えてください。binary fileをオープンして、1Byteずつc=fgetc(fp); を繰り返し読込み特定の処理します。数百万バイトを読んだあたりで、こけるので、何バイト目あたりでこけているのか知りたいというのが動機です。 fp構造体の中で、今、ファイルの冒頭から何バイト読んだところ、という情報を引っ張り出して1Byte読み込むごとに(ずらずらとでいいので)表示したいです。fp->current_byte とかいう情報があるように想像するのですが、どうでしょうか。以下に、#include<stdio.h>の中で、FILE を引用します。 typedef struct { unsigned char *curp; /* Current active pointer */ unsigned char *buffer; /* Data transfer buffer */ int level; /* fill/empty level of buffer */ int bsize; /* Buffer size */ unsigned short istemp; /* Temporary file indicator */ unsigned short flags; /* File status flags */ wchar_t hold; /* Ungetc char if no buffer */ char fd; /* File descriptor */ unsigned char token; /* Used for validity checking */ } FILE; /* This is the FILE object */

みんなの回答

  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.3

> ファイルサイズが 数百万バイトということであれば、ftell() の返り値が long なので、使えませんね。 何を書いてるんだ、あたしゃあ。 No.2 の回答のように、十分足りてますね m(_ _)m

harapeko99
質問者

お礼

ありがとうございます。詳しい人も、勘違いすることもある箇所の付近ということから、雰囲気が一層よく理解できたように思います。

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.2

ANSI C(C89)の場合。 ・int fseek(FILE *stream, long offset, int whence); ファイルポインタ移動関数だが移動させなければ現在位置が関数値として戻される ・int fgetpos(FILE *stream, fpos_t *pos); fseek(stream, 0,SEEK_SET)と同じ動作だが、関数値ではなくposに設定される fpos_tはファイルポインタの最大値を収めることのできる型として定義される ・long ftell(FILE *stream); 現在位置を関数値として報告するだけ longが32ビットの処理系でファイルサイズが2Gバイト以下ならlong ftell(FILE *)を使うのがまっとうな方法です。 ファイルポインタの最大値がlongに収まらないようならint fgetpos(FILE *stream, fpos_t *pos)ですね。 FILE構造体の構成は処理系依存なので、メンバ変数の用途はわかりません。 メンバ変数が存在しても利用されていない場合もあります。

harapeko99
質問者

お礼

ありがとうございます。実は、必要に迫られてご回答を見る前に、実装しました。それは偶然No.1の方のと同じ方法でした。No.2のご回答でお教えいただいたftellを知り、早速それもやってみると、うれしいことに同じ結果になりました。検算のように使えとても安心ました。ftell(fp)だと、一層すっきりしますし、簡便と思いました。ファイルポインタがlongの範囲を超えても、fgetpos()という関数が用意されているということが心強いです。ところで、どうやって、longの範囲を超えた値を調べるのかとか、fgetpos()の具体的な使用法を知りたくなってきました。

  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.1

ANSI の範囲では ftell() というライブラリがこの用途に使えるのですが、ファイルサイズが 数百万バイトということであれば、ftell() の返り値が long なので、使えませんね。 FILE の中をのぞくようなトリッキーなことをせず、カウンター用の変数を用意(*)しておいて fgetc() する度に +1 しましょう。   (*) カウンター用の変数も long では足りないですね

関連するQ&A

  • icon format について

    Visual Studio.NET 2003 MFC を使用しています。 View画面で、アイコンを表示しようと思いました。 アイコン読み込みようのクラスを作成しました。 class icon { public: void IconHeadRead(FILE *fp,int *width,int *height) { unsigned char uc; unsigned short us; unsigned int ui; fread(&us,sizeof(unsigned short),1,fp); fread(&us,sizeof(unsigned short),1,fp); fread(&us,sizeof(unsigned short),1,fp); fread(&uc,sizeof(unsigned char),1,fp);*width=uc; fread(&uc,sizeof(unsigned char),1,fp);*height=uc; fread(&uc,sizeof(unsigned char),1,fp); fread(&uc,sizeof(unsigned char),1,fp); fread(&us,sizeof(unsigned short),1,fp); fread(&us,sizeof(unsigned short),1,fp); fread(&ui,sizeof(unsigned int),1,fp); }; void IconDataRead(FILE *fp,unsigned char *red,unsigned char *green,unsigned char *blue) { unsigned char uc; fread(&uc,sizeof(unsigned char),1,fp);*red=uc; fread(&uc,sizeof(unsigned char),1,fp);*green=uc; fread(&uc,sizeof(unsigned char),1,fp);*blue=uc; }; }; このred,green,blueの値を使用して、 SetPixelでドローしようと思いましたが、 変な表示になります。 width,heightは、正しいようです。 ICON フォーマットについて教えてください。 よろしくお願いします。 同じような要領で、bitmapは保存、読み込みはできました。

  • プログラム(C)

    #include <stdio.h> #include <stdlib.h> #define FNAME "smp.bmp" #define WSIZE 256 #define HSIZE 256 #define BSIZE 1024 int main(void) { struct BMPFILEHEADER { ・   ・ }; struct BMPINFOHEADER { ・   ・ }; unsigned char img[HSIZE][WSIZE][3]; unsigned char buf[BSIZE]; struct BMPFILEHEADER lpHead; struct BMPINFOHEADER lpInfo; FILE *fp; int i; int j; int k; fp = fopen(FNAME,"rb"); if (fp==NULL) { printf("ファイルをオープンできません\n"); return 0; } fread(&lpHead.bfType, sizeof(unsigned short),1,fp); fread(&lpHead.bfSize, sizeof(unsigned int),1,fp); fread(&lpHead.bfReserved1, sizeof(unsigned short),1,fp); fread(&lpHead.bfReserved2, sizeof(unsigned short),1,fp); fread(&lpHead.bf0ffBits, sizeof(unsigned int),1,fp); fread(&lpInfo, sizeof(struct BMPINFOHEADER),1,fp); for(i=0;i<HSIZE;i++) { fread(buf,sizeof(unsigned char),WSIZE*3,fp); for(j=0;j<WSIZE;j++) { for(k=0;k<3;k++) { img[HSIZE-1-i][j][k]=buf[j*3+k]; } } } fclose; return 0; } このプログラムはBMP画像を読み込むプログラムなんですが このプログラムに画素値を出力するプログラムにしたいのですがうまくできません。 結果は(真っ白な画像の時)255255255・・・255255と出力したいのです。白黒画像なのでR=G=Bで1画素値は255だけでいいのですが。どうしても255255255や25500などとでてしまいます。 アドバイスお願いします。(800字までなので構造体の宣言は抜いてしましました) 。

  • 3次元配列でのポインタ

    唐突ですみません。 サイズが640*480の画像を180枚読み込むプログラムをポインタを使って作成しようと考えています。 以下で示すプログラムは画像を読み込むための作成したものですが、エラーが出てしまい実行することができません。 間違えている箇所があればご指摘お願いします。 また、そのほかに効率の良いやり方などがありましたらご教授願います。 #include <stdio.h> #include <stdlib.h> #include <math.h> #define xsize 640 #define ysize 480 #define round 180 #include "Input.h" void Input_task(unsigned char ***In); void main() {   static unsigned char ***In;   int i,j;   In=(unsigned char***)malloc(sizeof(unsigned char)*round);   for(i=0;i<round;i++)   {     In[i]=(unsigned char**)malloc(sizeof(unsigned char)*ysize);     for(j=0;j<ysize;j++)     {       In[i][j]=(unsigned char*)malloc(sizeof(unsigned char)*xsize);     }   }   Input_task(In); } Input.hの中身 void Input_task(unsigned char ***In) {   char filename[30];   int i,j,k;   FILE *fp;   for(i=0;i<round;i++)   {     sprintf(filename,"b20_%04d.raw",i);     fp=fopen(filename,"rb");    for(j=0;j<ysize;j++)     {       for(k=0;k<xsize;k++)       {         *(*(*(In+i)+j)+k)=(unsigned char)getc(fp);       }     }    fclose(fp);   } }

  • 変数 および ポインタのサイズ(バイト数)について

    sizeof演算子を使ってchar int float double型のバイト数を調べると、char 型については1バイトと決まっていて、int float doubleについては2から8バイト(処理系によって違う)なのは理解できます。しかし、char* int* float* double*型(ポインタ型)のバイト数は2から4バイトになるのが多いとおもいますが、どういう理由でポインタ型のバイト数が決まるのか、その理由をお教え願いたく思います。16ビットcpuあるいは32ビットcpuと言うハードの影響なのかそれとも何かソフトによるのか、その理由を知りたいと思います。なお私の処理系ではポインタは全て4バイトになっています。特に不思議に思うのはchar型は1バイトなのに、char*型が4バイトになっていることです。 宜しく願います。

  • 二次元配列のプログラミングが分かりません

    センサからは常に「#(ONかOFFが16)CR」全部で18個の情報が送られてきます。ONは1、OFFは0を返します。 この情報20回分を二次元配列に格納し、排他的論理和を取るプログラムを考えています。 *************************************** 例3回の場合 1回目#1101110000000111CR 2回目#0010110101110100CR 3回目#0110010100010101CR これを縦に排他的論理和を取っていきます。 まず1回目と2回目の排他的論理和をとる 次に2回目と3回目の排他的論理和をとる 最後に全部で1がいくつあったのかを表示 **************************************** このようなプログラムを書きたいです。どのように書いたらいいでしょうか。 <今できているプログラムは以下です> int main(void) { int i=1; int a=0; int A[20][18]; int b,c =0; char* Buffer; FILE *fp1; Buffer = (char*)calloc(1024,sizeof(char)); char port1[10]; sprintf(port1,"COM6"); fp1 = fopen("result.txt","w"); // ファイルを開く /*ポート設定省略*/ /* 配列の初期化*/ for(b=0;b<20;b++){ for(c=0;c<18;c++){ A[b][c]=0; fprintf(fp0,"%2d",A[b][c]); } } fclose(fp0); /********************************* 数を合わせる #が入ったら読み込み残りの17を拾う *********************************/ do{ CommPort1->ReadBytes((unsigned char*)Buffer,1); }while(*Buffer !='#'); CommPort1->ReadBytes((unsigned char*)Buffer+1,17); //残りの17byteを読み込む CommPort1->FlushCommPort(); //データの送受信 for(int i=0;i<20;i++){ //20回分のデータを読みこみ、テキスト出力 tuushin(Buffer); n++; fprintf(fp1,"%d=%s \n",n,Buffer); } fclose(fp1); return 0; } /**************************************************** 通信する関数 「#(ONかOFFが16個)endコード」、計18からなる文字列を読み込み表示 ****************************************************/ void tuushin(char*Buffer) { CommPort1->ReadBytes((unsigned char*)Buffer,18); CommPort1->FlushCommPort(); printf("%s\n",Buffer); } どのようにかけばいいのか分からないので、教えてください。

  • 構造体のメンバにファイルポインタがあるときの初期化について

    #include<stdio.h> typedef struct file{ FILE *fp; char filename[255]; int flag; }sFILE; main() { sFILE fp={ ,"output.txt",1100}; } のように書きたいんですが、sFILE fp={ ,"output.txt",1100};の最初のファイルポインタのところは何を入れたらいいんでしょうか?

  • FILE型からポインタ情報をもらうことはできますか?

    FILE fp; fp = fopen(filename, "r"); これでfpにfilenameのポインタが入ると思っているのですが、 filenameを何度かリードした後、fpからリードポインタの値を 取り出して、 int *Infile; に、代入したいのですがこれって出来ますか?

  • ポインタと配列

    次のソースで、結果表示でポインタを使いたいのですが、うまくいきません。1件しか表示されないのです。 ポインタの扱いがおかしいのだと思いますが、どうしたらよいでしょうか? #include <stdio.h> #include <string.h> int search(char key[256],FILE *fp,char *result[256][256]); main(void) { FILE *fp; int rep,n,i; char x[256],key[256],*result[256][256]; printf("検索キーワードを入力してください。\n" "キーワード>"); gets(key); if((fp=fopen("personal.txt","r"))==NULL) { printf("ファイルをオープンできません\n"); exit(1); } printf("=====検索結果=====\n"); n=search(key,fp,result); for(i=0;i<n;i++) { printf("%s\n",result[i]); } printf("検索結果:%d件です。\n",n); fclose(fp); } int search(char key[256],FILE *fp,char *result[256][256]) { int n=0; char *p,word[256],*name; while((p=fgets(word,256,fp))!=NULL) { if(strstr(word,key)!=NULL) { name=strtok(p," "); strcpy(result[n],name); n++; } } return n; } 実行すると、下の警告がでます。 illegal pointer combination(param)

  • 画像を読み込んでヒストグラムを作るプログラム

    2値化画像を読み込んで、ヒストグラムを表示させるプログラムを作りたいのですが、 以下のソースを作成したのですが実行中にエラーが発生して困っています。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #define width 640 #define height 480 int main(int argc, char* argv[]) { unsigned char image[640*480]; unsigned char header32[1078];//ビットマップ情報 int i; int *histogram; FILE *fp1; unsigned char buffer1[640*480]; for(i=0; i<640*480; i++) { image[i]=0; buffer1[i]=0; } fp1=fopen("koshimizu1.bmp","rb"); // fread(image,1,640*480,fp1); fread(header32,1,1078,fp1); fread(buffer1,width,height,fp1); fclose(fp1); for(i=0;i<256;i++){ histogram[i]=0; } for(i=0;i<640*480;i++){ histogram[image[i]]++; } for(i=0;i<256;i++){ printf("%d %d \n",i,histogram[i]); } return 0; }

  • GlobalAlloc生成メモリの開放でエラー

    とある大学生です. 研究でCのプログラムを書いており,メモリの生成と解放をしているのですが,どうしてもエラーが起きてしまい,困っております. そこで,この場をお借りして,みなさまにお力添えをしていただければと思い,質問しました. 問題のプログラムは以下のようになっております. ------------------------------------------------- #define BUFFER true FILE *fp = NULL; unsigned short int *lpBuffer = NULL; HGLOBAL hGlobal = NULL; char FilePath[] = "data.txt"; int DataDepth = 240; #if BUFFER unsigned short int buffer; #endif // 外部ファイル読み込みモード(r)で開く fopen_s( &fp, FilePath, "r" ); // ファイル読み込みモードで開く // データ領域の割り当て hGlobal = GlobalAlloc( GPTR, DataDepth*sizeof(unsigned short int) ); lpBuffer = (unsigned short int*)hGlobal; // 外部ファイルからデータ読み込み for( int i=0; i<DataDepth; i++ ){ #if BUFFER if( fscanf_s( fp, "%x", &buffer )!=EOF ) // 16進数で読み込む lpBuffer[i] = buffer; #else fscanf_s( fp, "%X", &lpBuffer[i] ); // BUFFER = true #endif // メモリ領域の開放 GlobalFree( hGlobal ); // BUFFER = falseのときエラー発生個所 // ファイルクローズ fclose( fp ); ------------------------------------------------- データファイル(data.txt)は以下のような構成になっており,240行あります. ------------------------------------------------- 0000 0001 0002 0003 .... 00EF ------------------------------------------------- このプログラムでBUFFER = trueのときは以下のようなエラーが本コード(関数)を終えた箇所で発生します.デバッグ実行で無視できます. +++++++++++++++++++++++++++++++++++++++++++++++++ Run-Time Check Failure #2 - Stack around the variable 'buffer' was corrupted. +++++++++++++++++++++++++++++++++++++++++++++++++ このプログラムでBUFFER = falseのときは以下のようなエラーが発生します.デバッグ実行で無視できないものです. +++++++++++++++++++++++++++++++++++++++++++++++++ Windows によって WinUSB_Control.exe でブレークポイントが発生しました。 ヒープが壊れていることが原因として考えられます。WinUSB_Control.exe または読み込まれた DLL にバグがあります。 あるいは、WinUSB_Control.exe がフォーカスを持っているときに、ユーザーが F12 キーを押したことが原因として考えられます。 +++++++++++++++++++++++++++++++++++++++++++++++++ ネットで調べて原因を調べたのですが,わからなく今に至ってます. 開発環境はWindows 7 64bitでMicrosoft Visual Studio 2010です. 原因や解決方法をご存知の方は,お力添えいただけたら幸いです. ご回答,よろしくお願い致します.

専門家に質問してみよう