• 締切済み

fread()エラー

お世話になります。 今、バイナリファイルを操作しているのですが、 fread()でエラーになってしまいます。 char buf1[256]; FILE *fp; vector<string> f1; int num; fp = fopen("hoge.txt","r"); while( fgets( buf1, sizeof(buf1),fp ){ f1.push_back( buf1 ); num ++; } fclose(fp); FILE *cfp; unsigned char data[1024]; for(int i=0; i<num; i++ ){ cfp = fopen(f1[i].c_str(), "rb"); fread( data, sizeof(char), 1024, cfp ); } hoge.txtには、コンテンツ場所(パス)が複数記載されており、 その1つずつをfread()で読み込み解析したいのですが、 fread()でセグメンテーション違反になります。 f1の中味をprintf("%s",f1[0].c_str()); で見てみると正常にコンテンツの場所が格納されています。 また、 string pp = "/home/hoge/hoge.txt"; cfp = fopen(pp.c_str(), "rb"); fread(bb,sizeof(char),1024,cfp); とすると正常に動作します。 どうぞよろしくお願い致します。

みんなの回答

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.8

回答されてる人のコードでは皆さんきちんと修正してるので 一応、本題とはちょっと離れるけどつっこみを。 以下のコードループの中でfopenを使用しcfpを上書きしてますが、 きちんとfcloseしましょう。 >FILE *cfp; >unsigned char data[1024]; >for(int i=0; i<num; i++ ){ >cfp = fopen(f1[i].c_str(), "rb"); >fread( data, sizeof(char), 1024, cfp ); >} >f1の中味をprintf("%s",f1[0].c_str()); このような場合は、使っている可能性のあるものすべてを 調べる必要があります。f1[0]がOKだったからといってそれ以降 f1[1]が大丈夫という保障はありません。 きちんと、ある程度の可能性まで考慮して調査してみると 良いと思います。

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.7

あっ、あと、size_t i など符号なし型を使う場合は、引き算や 0 との比較に注意してください。i が 0 なのに、--i や i - 1 などを気軽に使ってしまうと、巨大な数字に化けてしまいます(たぶん^^)。

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.6

ご参考: ==== C++ っぽく凝って書くと^^ #include <cstdio> #include <vector> #include <string> #include <fstream> #include <algorithm> #include <iterator> int main() { using namespace std; vector<string> f1; { ifstream ifs("hoge.txt"); istream_iterator<string> isi(ifs), ise; copy(isi, ise, back_inserter(f1)); } for(int i=0; i<f1.size(); i++ ){ FILE *cfp; if ((cfp = fopen(f1[i].c_str(), "rb")) == NULL) continue; unsigned char data[1024]; while (size_t sz = fread( data, sizeof data[0], sizeof data / sizeof data[0], cfp )) { // ... } fclose(cfp); } } === ファイルのパス名の中に空白がある場合、C++ っぽく普通に書くと^^ #include <cstdio> #include <vector> #include <string> #include <fstream> #include <cctype> std::string trim(const std::string &str) { std::string::size_type s = 0; while (s < str.size() && std::isspace(str[s])) ++s; std::string::size_type e = str.size(); while (s < e && std::isspace(str[e - 1])) --e; return str.substr(s, e - s); } int main() { using namespace std; vector<string> f1; { ifstream ifs("hoge.txt"); string ln; while (getline(ifs, ln)) f1.push_back(trim(ln)); } for(int i=0; i<f1.size(); i++ ){ FILE *cfp; if ((cfp = fopen(f1[i].c_str(), "rb")) == NULL) continue; unsigned char data[1024]; while (size_t sz = fread( data, sizeof data[0], sizeof data / sizeof data[0], cfp )) { // ... } fclose(cfp); } }

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.5

★アドバイス ・fopen() 関数でファイルパスに改行コードが含まれるとエラーになります。  あと num は 0 で初期化してから num++ しましょう。 サンプル: vector<string> path; char buff[ 256 ]; char *find; FILE *fp; int num = 0; ←初期化 // hoge.txt の読み込み if ( (fp = fopen("hoge.txt","r")) != NULL ){  while ( fgets(buff,sizeof(buff),fp) != NULL ){   if ( (find = strchr(buff,'\n')) != NULL ){    *find = '\0';   }   path.push_back( buff );   num++;  }  fclose( fp ); } // 各ファイルを読み込む unsigned char data[ 1024 ]; for ( int no = 0 ; no < num ; no++ ){  if ( (fp = fopen(path[no].c_str(),"rb")) != NULL ){   size_t size = fread( data, sizeof(char), sizeof(data), fp );      // バイナリー検索   for ( int i = 0 ; i < (size - 1) ; i++ ){    if ( (data[i] == 0xFF) && (data[i + 1] == 0xE0) ){     printf( "find:%d\n", (data[i] << 8|data[i + 1]) );    }   }   fclose( fp );  } } その他: ・fread() で読み取れたバイト数をバイナリー検索して下さい。  あと data[1024] なので i カウンタは 0~1023 ですが 16 ビットのデータを  検索する場合は i カウンタを 0~1022 までの検索にします。注意。 ・以上。

the-ai
質問者

お礼

ありがとうございました。無事に解決できました。

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.4

> それと、テキストファイルは "r" がいいです。 あっ、失礼。"r" になってますね^^; すみません。

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.3

あぁ、そうそう。gets と fgets の違いに注意してください。てか、C++で使わない、のがいい^^

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.2

fopen() が失敗してるんだと思いますよ。 ファイル名の後に、改行が入ってしまっているんじゃないですか? それと、テキストファイルは "r" がいいです。 それに、num を初期化しましょう。 そして、きちんと、関数の戻り値をみて、エラー処理をしましょう。エラーが起こってからでもできる、というならそれでもいいですけどねぇ。。。 ・NULL を使う場合は省略せずにきちんと NULL と比較したほうがいい ・fopen() の戻り値は必ずチェックする ・fread() の返してくるサイズはきちんと受ける ・C++なら、変数の宣言は使う必要があるところで宣言する あと、せっかく C++ なんだし、バイナリのファイルじゃない場合は、fstream とか使えばいいのに^^

  • RAPTsong
  • ベストアンサー率42% (74/175)
回答No.1

> int num; num が初期化されていないからでは? それで、配列の添え字が範囲外アクセスしているのでしょう。

関連するQ&A

  • fread

    freadで、a.txtの内容を画面出力するものです。 コピーした結果、 実際のテキストにある、 !  が書き込まれませんでした。 どこが、間違っているか教えてください。 FILE *fp; char str[20];   fp=fopen("a.txt","rb");   while(!feof(fp)){      fread(&str,(sizeof(str)-1),1,fp);      if(feof(fp))            break;      printf("%s",str); }      return 0; }

  • FILE オープンについて

    いつもお世話になります。 今ファイルデータ検索処理を検討しております。 今、search.txtには、 検索対象となるファイルパスが記載されています。 [search.txt] /home/hoge/SAMPLE1.jpg /home/hoge/SAMPLE2.jpg search.txtをfopen()し、1行ずつfgets()して、 得られるファイルパスより、そのファイルを fopen()して解析する処理がしたいですが、 fgets()より得られたファイルパスをfopen()し、 fread()するとセグメンテーションエラーになります。 どのようにしたらいいのでしょうか? 現状のコードを下記します。 FILE *fp; char *com1 = "/home/hoge/search.txt"; FILE *confp; char buf1[1024]; char buf2[1024]; int i =0; fp = fopen(com1, "r"); while( fgets(buf1, sizeof(buf1), fp )){ confp = fopen(buf1, "rb"); //*.JPGファイルをオープン //下記fread()でセグメンテーションエラー size_t size = fread( buf2, sizeof(char), 1024, confp ); for( i = 0; i<1024; i++ ){ if( (buf2[i] == 0xff) && (buf2[i+1] == 0xe0) ){ printf("%02x\n",buf[i+5]); } } } fclose(fp); fclose(confp); 上記のように、search.txtをfopen()し、読み込んだファイルパスを fopen()して、fread()読み込みをする方法を 教えて下さい。 どうぞよろしくお願い致します。

  • fread関数でわかりません。

    fread関数で次のようにソースを記述しました。 FILE *fp; char c[10]; int i; fp = fopen ("./aaa.txt", "rb"); fread(c, sizeof(char)-1, 10, fp); for(i = 0; i < 10; i++) printf("%02x ", *(c+i)); fclose(fp); return 0; aaa.txtの中には 0x1~0xAの10個の数字が記入されています。 cをint 型にすると正常に読み込めるのですが、char型だと 01 00 00 00 02 00 00 00 03 00 となってしまい、正常に読み込めません。 どうも、int型で読み込み、さらに引数 cにはchar *でキャストして渡しているように見受けられます。 Q1 どのようにしたら、char型で 10個一度に読み込めるようになるのでしょうか? Q2 int型(32bit)なら、一度に4文字読み込むと思いますが、何故一文字ずつ読み込むことになるのでしょうか? //getc で一文字ずつ読み込めば済む話ですが、気になり質問いたしました。

  • fread処理がうまくいかない!!

    バイナリエディタでfwriteで書き込んだデータは確認できたのですがfread後のデータがきちんと表示されません。 どうしてでしょうか? #include <stdio.h> void main(void) { char i[] = {'a','b'}; char j[2]; FILE *fpbin; fpbin = fopen("data","wb+"); fwrite(&i,sizeof(char),2,fpbin); fpbin = fopen("data","rb"); fread(&j,sizeof(char),2,fpbin); printf("j = %c\n", j[0]); fclose(fpbin); }

  • fread

    fread関数を使用し、下記のように 同じファイルに上書きしているのですが。。。。 freadで取得したデータの全角コロンを半角コロンに置き換える。 その後、全角空白を半角空白におきかえる。 そのおきかえたデータを同じファイルの上書きする。 どうもコロン(:)のところがうまく書き変えられていません。。。。 おきかえた後に、print文で出力すると置き換えられているのですが、、、 この現象がわかる方教えていただけませんか?? $body=fread(fopen($fileName, "r"),filesize($fileName)); $txt=str_replace(":", ":",$body); $txt=mb_convert_kana($txt, "s","SJIS"); $fp = fopen($fileName, "w"); chmod($fileName,0777); flock($fp, LOCK_EX); fputs ($fp, $txt); flock($fp, LOCK_UN); fclose($fp);

    • ベストアンサー
    • PHP
  • ファイルサイズを変更したい

    visualstudio2010を使用しています。 c言語で書いているのですが、 test.txt ←abcdefg ファイルサイズ1KB Wtest.txt←書き込み用ファイル 上記のようなファイルがあり、バイナリでtest.txtを読み込みWtest.txtに書き込みたいと思っています。 その際に、1KBのtest.txtを5KBになるまでバイナリで「abcdefg」の後に0を代入したいのですがどう書けば良いのかわかりません。 FILE *fp, *fpw; char *fname = "test.txt"; char *fname_w = "Wtest.txt"; unsigned char buf[10000]; int size; fp = fopen( fname, "rb" ); if( fp == NULL ){ printf( "%sファイルが開けません\n", fname ); return -1; } fpw = fopen(fname_w, "wb"); if(fpw == NULL){ printf( "%sファイルが開けません\n", fname_w ); return -1; } size = fread( buf, sizeof( unsigned char ), sizeof (fp), fp ); /*ここに処理を追加したい*/ fwrite( buf, sizeof( unsigned char ), size, fpw);

  • 16進数から10進数に変換

    いつもお世話になります。 先日バイナリデータを読み込み、ある特定のデータを検索し、 そのデータを10進数に変換する処理がしたいです。 FILE *fp; char buf[1024]; fp = fopen("sample.jpg","rb"); fread(buf, siZeof(char), 1024, fp); for( int i=0; i<1024; i++ ){ if( (buf[i]==0xff) && (buf[i+1] == 0xe0) ){ //※質問詳細下記します。 } } ※ f文で、buf[i+2]buf[i+3]、例えばprintf("%02x,%02x",buf[i+2],buf[i+3]); で出力すると、所望の(11 00 )の16進数で得られています。 このbuf[i+2] buf[i+3]の値を10進数に変換して得るには、 どうしたらいいでしょうか? 0x1100→4352 どうぞよろしくお願い致します。

  • freadでダンプ なぜ?

    ファイルを1バイトづつfreadで読み込んで ダンプしているのですが、なぜか16進数で"1A" (10進数で"26")の文字から先をダンプできません。 原因が良くわかりません。 どなたか、わかる方お助けください。  char buf[20];  unsigned short a;  flag = 1;  while (flag == 1){   fread(buf, sizeof(char), 1, fp_in);   a = buf[0];   printf("%02x ",a);   cnt++;   if(cnt == 16){    printf("\n");    cnt = 0;   }     :     : }

  • newかFILEでエラーのような

    エラーがおこらないと思うんだけど、実行時エラーです。 コンソールアプリケーションのソースを見てください。 fclose(fp); を2行上に移動した場合はエラーにはなりません。 これはどうしてエラーになるんですか? test.txtは、同じディレクトリにある0バイトのファイルです。 #include <windows.h> #include <iostream.h> int main(){  WIN32_FIND_DATA finddata;  FILE *fp;  char *str;  char **pp;  FindClose(FindFirstFile("test.txt", &finddata));  fp = fopen("test.txt", "r");  if(fp){   str = new char[14];   fclose(fp);   strcpy(str, "abcdefghijklm");   pp = new char*[3];   pp = &str;   delete [] *pp;   delete [] str;  }else cout << endl;  return 0; }

  • freadの最後

    100文字くらいのファイルのファイルポインタfpがあるとして、 char ch[200]; fread(ch,sizeof(char),sizeof(ch),fp) とした場合にchの中で、ファイルの最後っていうのを判断するにはどうすればいいですか?