• 締切済み

ファイル処理について

大学の課題なのですが、何度取り組んでもエラーになるため、間違いのご指摘、または正答を教えていただけないでしょうか。 問題は以下のものです。 【問題】 ファイルから整数を読み込み,その値によってfpの読み込み位置をかえ,何度目の読み込みで0を読み込んだかを表示するプログラムを作成せよ. ファイルの内容の例 2,4,0, fpの読み込み位置を変えるにはfseekという関数を利用する. fseekの使い方: 現在の読み取り位置xだけずらすには, fseek(ファイルポインタ, x, SEEK_CUR); と記述する. STEP 1 データを一区切りで読み取る("2,"や"-4,"などの整数とコンマの組) 2 読み取ったデータに応じてfpを移動させる("2,"なら2移動,"-4,"なら-4移動) 3 0を読むまで繰り返す +++++*+++++fseek-exercise.c+++++*+++++ #include <stdio.h> int main(void){ FILE *fp; int c; int i; int count=0; char filename[60]; printf("ファイル名 :"); scanf("%s",filename); //ファイルを開く // (* ここに解答を書き加える *) while(1){ printf("読み込み前 : %ld\n",ftell(fp)); //fpから値を読む // (* ここに解答を書き加える *) printf("読み込んだ値は%dです\n",c); printf("読み込み後 : %ld\n\n",ftell(fp)); //読み込み位置をずらす // (* ここに解答を書き加える *) } printf("%d回目です.",count); fclose(fp); return(0); } // 以上になります。 自分で作ったプログラムは以下のようになりました。 #include <stdio.h> int main(void){ FILE *fp; int c; int i; int count=0; char filename[60]; printf("ファイル名 :"); scanf("%s",filename); //ファイルを開く // fp = fopen(filename,"r"); if(fp == NULL){ printf("cannot open\n"); exit(1); } while(1){ printf("読み込み前 : %ld\n",ftell(fp)); //fpから値を読む // c = fgetc(fp); printf("読み込んだ値は%dです\n",c); printf("読み込み後 : %ld\n\n",ftell(fp)); //読み込み位置をずらす // if(c > '0' || c< '9'){ i = atoi(&c); count++; if(i == 0){ break; } fseek(fp,i,SEEK_CUR); } } printf("%d回目です.",count); fclose(fp); return(0); } // どこを訂正していいのかわかりません。 どうぞ、よろしくお願いいたします。

みんなの回答

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.4

>STEP >1 データを一区切りで読み取る("2,"や"-4,"などの整数とコンマの組) >2 読み取ったデータに応じてfpを移動させる("2,"なら2移動,"-4,"なら-4移動) >3 0を読むまで繰り返す 「『整数とコンマの組』単位の移動」と曲解して作ってみました(BorlandC++5.5.1)。 というか、「文字単位での移動」だと、移動の途中に、2桁の整数・負数などがあると、難しくて・・。   ・データによっては、無限ループとなります。     2( 2, )進んで2( -2, )戻る場合など・・。   ・データによっては、「 0を読むまで繰り返す」ことができません。 ・という訳で、参考にもならんかも・・。 サンプルデータ:12,31,32,33,34,35,36,37,38,39,10,11,-2,-3,-4,-5,-6,-7,-8,-9,-0,1, (プロセス) :12,--,--,--,--,--,--,--,--,--,10,--,-2,--,--,--,--,--,--,--,-0,-, #include <stdio.h> int main( void ) {  FILE *fp;  int iIdou, count = 0, iCmmCnt, c;  fp = fopen( "Z:\\Test.txt", "rb" ); // バイナリストリームモード // (略)  while( 1 ){   printf( "\t読み込み前 : %ld\n", ftell( fp ) );   if( 1 != fscanf( fp, "%d,", &iIdou ) ) break;   printf( "[%d]\t読み込んだ値は %d です\n", ++count, iIdou );   printf( "\t読み込み後 : %ld\n\n", ftell( fp ) );   if( ! iIdou ) break; // 0発見   iCmmCnt = 0;   if( 0 > iIdou ){ // ←負:左へ    while( iCmmCnt > ( iIdou - 2 ) ){     if( fseek( fp, -1, SEEK_CUR ) ) break;     c = fgetc( fp ); fseek( fp, -1, SEEK_CUR );     if( ',' == (char)c ){      iCmmCnt--;      if( iCmmCnt == ( iIdou - 2 ) ) fseek( fp, 1, SEEK_CUR );     }    }   }   if( 0 < iIdou ){ // →右へ    while( iCmmCnt < ( iIdou - 1 ) ){     c = fgetc( fp );     if( ',' == (char)c ) iCmmCnt++;    }   }  }  printf( "%d 回目です.", count );  fclose( fp );  return( 0 ); } 注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.3

1 データを一区切りで読み取る("2,"や"-4,"などの整数とコンマの組) は fscanf(fp, "%d,", &num); という意図かなと思いました。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.2

ひとつ訂正。 > if(c > '0' || c< '9'){ この条件式ではif(1)と同じ(必ず真)です。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.1

まず質問する上での基本中の基本ですが「どううまくいかない」のか詳細を書きましょう。 エラーが出るなら何をやったらどんなエラーが出るのか。 ざっくり見た上では以下の箇所に問題あります。 > c = fgetc(fp); > printf("読み込んだ値は%dです\n",c); > printf("読み込み後 : %ld\n\n",ftell(fp)); charの'0'~'9'は数値の0~9ではないので期待する値は表示されません。 > if(c > '0' || c< '9'){ この条件式では'0'と'9'を含みません。 > i = atoi(&c); atoi()に渡すのは文字列('\0'で終端されたchar配列)でなければなりません。単品のcharのアドレスを渡した場合、次のアドレスの中身が不定のため実行結果は不定(最悪Segmentation fault)になります。

関連するQ&A

  • ファイルの大きさを調べたいのですが、、、(C言語)

    2週間前にC言語の勉強を始めたばかりです。 「あるファイルのサイズを見て、メモリを確保し、  読み出した内容をソートして、同じファイルに再び書き出す」 というプログラムを作ろうとしているのですが、 「ファイルのサイズを調べる」という時点でつまづいてしまっています。。。 適当に英数字を書き連ねたファイル(aaa.txt)を、 (fp = fopen(filename,"a+") という形で開いています。 追加読み書きするので"a+"かな? と思ったのですが、、、   //ファイルの終端に移動し、その位置を取得する   fseek(fp1, 0L, SEEK_END);   position = ftell(fp1);   printf("ファイルポインタの位置は %ld です",position); ファイルの大きさを調べるのに、この方法を試してみたのですが、 位置の値が0になってしまいます。。。 filelength(fileno(fp)); でも試してみましたが、 やっぱりファイルサイズが0と返ってきます。 何が原因なのか、何が悪いのかも判らなくて途方に暮れています。 「ここはこう書くんだよ」と、的確なご回答を戴けると幸いです。 基本的な質問で申し訳ありませんが,宜しくお願い致します。

  • ファイルサイズの取得について

    2つのテキストファイルのサイズを取得し、そのファイルサイズ分だけを動的にメモリを確保しようとしています。 int *c,*a;と宣言し、 fp=fopen("./data/Problem.txt","r");//1つ目のファイル fseek(fp, 0, SEEK_END); /* ファイルの終端までシーク */ size = ftell(fp); /* 終端の位置、すなわちファイルサイズを得る */ fseek(fp, 0, SEEK_SET); /* ファイルの先頭に戻る */ c = (int *)malloc(size); /* ファイルサイズ分メモリ確保 */ while((x=fgetc(fp))!=EOF){ c[i]=x; i++; } c[i]='\0'; i=0; fclose(fp); fpa=fopen("./data/Answer.txt","r");//2つ目のファイル fseek(fpa, 0, SEEK_END); size = ftell(fpa); fseek(fpa, 0, SEEK_SET); a = (int *)malloc(size); while((x=fgetc(fpa))!=EOF){ a[n]=x; n++; } a[n]='\0';//・・・・(1) n=0; fclose(fpa); とすると1つ目のファイルの方だけはうまくいくのですが、(1)の部分で 「sample.exeの0x00411dcでハンドルされていない例外が発生しました:0xc0000005:場所0x0000000に書き込み中にアクセス違反が発生しました。。」 というエラーが出ます。 また、 int *c,*a;を int *c,a[300]; のように片方を配列として宣言し、 //a = (int *)malloc(size); /* ファイルサイズ分メモリ確保 */ のようにコメントアウトすると上記のエラーは出ずにcにメモリは確保されているようです。 これは何故なのでしょうか? また、どうすればaとcでメモリを確保出来るようになるのでしょうか? よろしくお願いいたします。

  • C言語のファイル処理について

    環境 OS:Windows VISTA Ultimate コンパイラ:Borland C++ Compiler 5.5 Cの基礎的な勉強をしています。2つほど質問があります。 1つ目は、ファイル処理の勉強としてプログラムを作っているのですがファイルが上手く開けません。プログラムとしてはファイルを開いて、ファイル内に記述されている数値を取り出し、計算を行う簡単なものを作っています。ソースは以下のものになります。 #define N 256 int file_read(char filename[] , int count[]) { int m; FILE *fp; fp=fopen(filename,"r"); if(fp==NULL) { /* オープン失敗 */ printf("Not Found File\n"); return -1; /* 戻り値-1 */ } while((m = fgetc(fp)) != EOF) { 読み取った数値配列に格納する処理 } fclose(fp); return 0; } int operation(int count[]) { 計算処理 return 0; } int main(void) { int *count[N]; char *filename[256]; memset(count, 0, sizeof(count)); /* 変数・配列初期化 */ printf("Please Input Filename:"); fgets(filename, sizeof(filename), stdin ); if(file_read(filename,count) != -1) operation(count); return 0; }  バッファオーバーランの事を考え、fgetsによるキー入力にしたのですがファイルオープン失敗になってしまいます。fgetsのあと、変数filenameの中身を確認したところ、キー入力した文字はきちんと代入されていました。オープンするファイルはきちんとあるのですが・・。  fgetsをscanfに変えた場合は上手くいくので書式指定をしてscanfを使えばいいのでしょうが、なぜfgetsで上手くいかないでしょうか? 2つ目はgetchar()とfgets()に関してです。 while((c = getchar()) != EOF) { . .処理 . fgets(変数, sizeof(変数), stdin ); . .処理 . } とした場合、fgetsの処理が無視されてしまいます。 これはどういったことが原因なのでしょうか。 ご教授、お願いいたします。

  • テキストデータから構造体にデータを保存する方法

    C言語初心者です。 大きなテキストデータ(730MB)からデータを取得して、構造体に保存し表示するというプログラムを作成しています。テキストのサイズが大きいため構造体のサイズを400000とし、 残りをftellとfseekを使用してファイルポインタをずらして全データを順次読み込んで表示しようとしているのですが、実行すると400000行目以降(最初の構造体のMAX時点)がうまく読み込めません。 詳しい方がいましたら、ご教授願います。 #define MAX_SIZE 400000 char filename[] = ″test.txt"; struct ALL_DATA{ char cmd[10]; int addr; int bsize; }; for (int lp = 0; lp < 100; lp++){ FILE *fp; struct ALL_DATA ADATA[MAX_SIZE]; // 構造体配列の宣言 if (lp > 0){ fseek(fp, LP, SEEK_SET); } if ((fp = fopen(filename, "r")) == NULL){ printf("%s open error !\n", filename); exit(1); } for (fc = 0; fc < MAX_SIZE; fc++) { if (feof(fp)){ break; } else{ fscanf(fp, "%s %d %d\n", ADATA[fc].cmd, &ADATA[fc].addr, &ADATA[fc].bsize); } } LP = ftell(fp); //現在のFPの取得 printf("********** FP-> %ld *********\n", LP); fclose(fp); while (i < MAX_SIZE){ if (loopcnt == 0){ printf("ADATA[i].cmd -> %s, ADATA[i].addr -> %d, ADATA[i].bsize -> %s\n",ADATA[i].cmd, ADATA[i].addr, ADATA[i].bsize); // i++; } } 上記のような形で作成しています(一部抜粋)。 読み込むテキストデータは testA 123456 20 testA 23415 2 testB 12114567 678 のように「文字列 スペース 数字 スペース 数字」と並んでおり 値はランダムになっています。 初めて質問するため、わかりにくい記述があるかと思いますが、よろしくお願いします。

  • ファイルの置換

    ファイルを置換するプログラムを作ったのですがうまく置換してくれません。コードは以下のように書きました。(コンパイラは出来ました) #include <stdio.h> #include <stdlib.h> #include <string.h> #define FALSE 0 #define TRUE 1 main() { FILE *fp; char filename[256]; FILE *outfp; char outfilename[256]; char key[128]; char str[128]; char c; int p; int keylen; int i=0 ; int search=FALSE; int count =0; printf(" enter filename"); scanf("%s",filename); printf("seach word"); scanf("%s",key); keylen=strlen(key); printf("change word"); scanf("%s",str); if((fp=fopen(filename,"r"))==NULL) { printf("file open error"); exit(1); } strcpy(outfilename,filename); strcat(outfilename,"_"); if((outfp=fopen(outfilename,"w"))==NULL) { printf("file open error"); exit(1); } while((c=fgetc(fp))!=EOF) { if(search) { if(c != key[i]) { search=FALSE; for(p=0;p<i;p++) { fputc(key[p],outfp); } fputc(c,outfp); i=0; } else{i++;} } else { if(c==key[i]) {search=TRUE;i++;} else {fputc(c,outfp);} } if (keylen==i) { count++; fputs(str,outfp); search=FALSE; i=0; } } fclose(fp); fclose(outfp); printf("apperance number %d\n",count); return 0; } どこか間違っていますか?教えてください。

  • 【C言語】ファイルを読み込んで16進数で表示する

    ファイルをバイナリモードで読み込んで16進数で表示するプログラムについて質問です。 以下の処理内容が理解できません。どのような処理を行っているのでしょうか?? (xdump.c)********************************* #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int i, j; FILE *fp; if(NULL == (fp = fopen(argv[1], "rb"))) { fprintf(stderr, "Cannot open FILE[%s].\n", argv[1]); exit(1); } for(i=0; i<0x7FFF; ++i) { printf("%08X :", ftell(fp)); for(j=0; j<16; ++j) { int c; c = 0x00FF & getc(fp); if(ferror(fp)) { puts("\a>>>> Read Error ! <<<<"); break; } if(feof(fp)) break; /* 16進数で表示 */ printf(" %2X", c); } printf(" : %08X\n", ftell(fp)-1); /* : */ /* : */ /* 以下省略 */ ****************************************** 上記に関して、 最初のfor文から"c = 0x00FF & getc(fp);"までの処理内容が よくわかりません。どなたかご教授願えますでしょうか?

  • ファイル

    AからZまでの文字が何回出力されるか数えるプログラムなのですが、うまく出力されません。 どこを変えればよろしいでしょうか。 #include<stdio.h> #include<stdlib.h> #include<ctype.h> int count[26]; int main(void) { char str[100] = "xyzYZZ\n"; FILE *fp; char *p; int i; char ch; if((fp = fopen("myfile","w")) == NULL){ printf("ファイルを開くことが出来ません"); exit(1); } p = str; while(*p){ if(fputc (*p,fp) == EOF){ printf("ファイル書き込みエラー"); exit(1); } p++; } fclose(fp); if((fp = fopen ("myfile","r")) == NULL){ printf("ファイルを開くことが出来ません"); exit(1); } while((ch == fgetc(fp)) != EOF){ ch = toupper(ch); if( ch >= 'A' && ch <='Z' ) count[ch - 'A']++ ; } for( i=0 ; i<26 ; i++) printf("%c は %d 回出現\n",i + 'A', count[i]); fclose(fp); return 0; }

  • CSVファイルを読み込み構造体のメンバ、"value"に格納し、その後

    CSVファイルを読み込み構造体のメンバ、"value"に格納し、その後平均値を求めて構造体のメンバ、"ave"に格納し表示させたいのですが、読み込み格納している最中で、セグメンテーション違反で終了してしまいます。どなたかよろしければ教えて頂けないでしょうか。 プログラム ************************************************** #include <stdio.h> #include <string.h> #include <stdlib.h> #define SIZE 64 #define FILE_NAME_00 "f_00_01.CSV" struct Data{ double value; double ave; }; int main(int argc, char *argv[]) { FILE* fp,*fo; // ファイルポインタ用 int n, i, file_size; struct Data *dat; if ((fp = fopen(FILE_NAME_00,"r")) == NULL) { printf( "file open error\n" ); exit(EXIT_FAILURE); } fseek(fp, 0, SEEK_END); file_size = ftell(fp); dat = (struct Data*)malloc(file_size); printf("malloc address= %p, file size= %d\n", dat, file_size); fseek(fp, 0, SEEK_SET); i = 0; for(i=0;i<file_size;i++){ fscanf(fp,"%lf",&dat[i].value); printf("%lf\n",dat[i].value); i++; } fclose(fp); printf("\n"); free(dat); return 0; } *************************************************** f_00_01.CSV *************************************************** 2.313725 2.312810 2.314031 2.316167 2.315557 2.313725 . . . . . ***********************************************

  • C言語 バイナリファイルをfloatにしたいのですが…

    16進数で表示すると以下のようなバイナリファイルがあります。 42 b9 e0 a4 3b df ea c0 3a 70 eb dc 37 7c f4 8c これを4バイトずつfloatに入れて出したいのですが、 本当はこのように出したいのですが、 [0][92.93875] [1][0.0068334043] [2][9.190419E-4] [3][1.50773085E-5] このような値がでてしまいます [0][-9.745835E-17] [1][-7.339750E+00] [2][-5.301601E+17] [3][-3.766891E-31] ソースはこれです。 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *fp; long size, n; float *buf; int i = 0; if (argc != 2) return 1; /* FILE OPEN */ fp = fopen(argv[1], "rb"); if (fp == NULL) return 1; /* FILE SIZE */ fseek(fp, 0, SEEK_END); size = ftell(fp); rewind(fp); printf("FILE SIZE %ld\n", size); /* FILE READ */ buf = malloc(size); if (buf == NULL) return 1; n = fread(buf, 1, size, fp); /* FILE PRINT */ for(i=0;i<10;i++) { printf("[%d][%E]\n", i, buf[i]); } return 0; } 本日一日調べましたが良くわかりませんでした。 開発環境は以下の内容です。 $ uname -a Linux fedoracore6 2.6.20-1.2962.fc6 #1 SMP Tue Jun 19 19:27:14 EDT 2007 i686 athlon i386 GNU/Linux $ gcc --version gcc (GCC) 4.1.2 20070626 (Red Hat 4.1.2-13) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 何かお知恵を拝借出来ないものでしょうか?? よろしくお願い致しますm(_ _)m

  • ファイルから一文字ずつ読み込む

    ファイルを読み込むfgetc()関数のところでプログラムが停止します。 以下が実行したプログラムです。 #include<stdio.h> void get_name(char name[],int a){ printf("ファイル名を入力してください。\n"); scanf("%s",name); } void open(FILE *fp2,char name[]){ if((fp2=fopen(name,"r"))==NULL){ printf("ファイルオープンエラー"); } } int count(FILE *fp3){ int ch=0; int count=0; if(fp3==NULL){ printf("error"); } while((ch=fgetc(fp3))!=EOF){ if(ch=='\n'){ count++; } } printf("TEST"); fclose(fp3); return(count); } int main (void){ FILE *fp; char fname[30]; get_name(fname,30); open(fp,fname); printf("%d",count(fp)); return(0);} ファイル名を入力してください。ファイル名を入力、プログラム停止です。 '\n'を数えれるようにしてください。御指摘お願いします。

専門家に質問してみよう