• ベストアンサー

ファイル入出力について教えて下さい。

ご覧いただきありがとうございます。 数値を入力して、数値を出力する方法を教えて頂きたいです。 ・   ・   ・ fp = fopen( "a.txt", "a" ); for( i = 16383; i >= 0; i-- ) { fprintf( fp, "%d", i ); } fclose( fp ); ・   ・   ・ data = (int *)malloc(32768); fp = fopen( "a.txt", "r" ); for( i = 0, i <= 16383; i++ ) { fscanf( fp, "%d", data+i ); } fclose( fp ); ・   ・ ・ 以上の記述で、入力はうまくいくのですが、出力の際に数値でなくなってしまいます。どうしてでしょうか? ご存じの方がおりましたら、ご回答よろしくお願いいたします。

noname#30991
noname#30991

質問者が選んだベストアンサー

  • ベストアンサー
  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.2

読み書きする数値に区切り記号がありません。このため、fscanf()が期待した動作をしません。 intの長さをchar*2と決め打ちしています。実際は4のことが多いのでオーバーフローします。sizeof()で大きさを決めましょう。 -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< #include <stdio.h> #include <malloc.h> #define IMAX 16383 int main(void) { FILE *fp; int * data; int i; fp = fopen("a.txt", "a"); for (i = IMAX; i >= 0; i--) { fprintf(fp, "%d ", i); } fclose(fp); data = (int *) malloc((IMAX+1)*sizeof(int)); fp = fopen("a.txt", "r"); for (i = 0; i <= IMAX; i++) { fscanf(fp, "%d ", data + i); } fclose(fp); for (i = 0; i <= IMAX; i++) { printf("%d\n", *data + i); } return 0; }

その他の回答 (4)

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

★別人ですが回答者 No.4 さんの『回答への補足』について ・『fscanf』関数の戻り値で判定する方が簡単かもしれませんよ。  戻り値は読み込んだフィールド数を返します。この数をチェックしてループ処理を  抜けるようにすると楽です。また『malloc』関数ではなくて『calloc』関数にする事で  すべての配列内容をゼロに初期化してくれます。これを組み合わせれば『fscanf』  関数の戻り値で EOF や 0 が返されたときにループ処理を抜けるだけで、入力されなかった  残りの配列データはすべて『0』を入れた状態になります。 ・下のソースを参考にして下さい。 参考ソース: #define IMAX 16383 int main( void ) {  FILE *fp;  int *data;  int i, ret;    if ( (fp = fopen("a.txt","a")) != NULL ){ ←戻り値をチェックしましょう。   for ( i = 1 ; i <= IMAX ; i++ ){    fprintf( fp, "%d ", i );   }   fclose( fp );  }  if ( (fp = fopen("a.txt","r")) != NULL ){ ←戻り値をチェックしましょう。   if ( (data = (int*)calloc(IMAX * sizeof(int))) != NULL ){    for ( i = 0 ; i < IMAX ; i++ ){     ret = fscanf( fp, "%d ", &data[i] );          if ( (ret == EOF) || (ret == 0) ){ ←ファイルの終わりか、フィールド数がゼロ      break; ←ループ処理を抜ける     }    }    for ( i = 0 ; i < IMAX ; i++ ){     printf( "%d\n", data[i] ); ←確認のための出力    }    free( data ); ←念のため解放   }   else{    printf( "メモリ不足です。\n" );   }   fclose( fp );  }  return( 0 ); } 最後に: ・『if(ret = feof(fp) == 0){ … }』の部分はカッコを付けた方が分かりやすいですよ。  あと『ret』変数は参照されていないので必要ないのでは?  つまり『if( feof(fp) ){ EOFの処理 }else{ データ処理 }』の記述でいいと思います。  『feof』関数は『0』か『0以外』を返しますので『feof(fp)』か『!feof(fp)』として  判定すれば分かりやすいですよ。 ・以上。おわり。

参考URL:
http://www1.cts.ne.jp/~clab/hsample/Primary/Io5.html
noname#30991
質問者

お礼

大変遅くなりましたが、ご回答ありがとうございました。 まだまだ初心者ですので、色々と見落とした点や知らない知識を気づかせていただき大変勉強になりました。 参考ソースもありがとうございました。

  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.4

No.2です。No.3さんフォローアップありがとうございます。 -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- #include <stdio.h> #include <malloc.h> #define IMAX 16383 int main(void) { FILE *fp; int * data; int i; fp = fopen("a.txt", "a"); for (i = IMAX; i >= 0; i--) { fprintf(fp, "%d ", i); } fclose(fp); data = (int *) malloc((IMAX+1)*sizeof(int)); fp = fopen("a.txt", "r"); for (i = 0; i <= IMAX; i++) { fscanf(fp, "%d ", &data[i]); } fclose(fp); for (i = 0; i <= IMAX; i++) { printf("%d\n", data[i]); } return 0; }

noname#30991
質問者

お礼

>読み書きする数値に区切り記号がありません。このため、fscanf()が期待した動作をしません。  その通りだったようです。 >intの長さをchar*2と決め打ちしています。実際は4のことが多いのでオーバーフローします。sizeof()で大きさを決めましょう。  わかりました。大変参考になりました。 二度のご回答、誠にありがとうございました。また、全ソースの記述までしていただき大変嬉しく思います。

noname#30991
質問者

補足

引き続き、すいません。 a.txtにいくつ数字が入っているかわからなくて、16383個に満たなければ「0」を入れたい場合には、 data = (int *) malloc((IMAX+1)*sizeof(int)); fp = fopen("a.txt", "r"); for (i = 0; i <= IMAX; i++) { if( ret = feof( fp ) == 0 ) { fscanf(fp, "%d ", &data[i]); } else { fscanf(fp, "%d", &data[i]); } } fclose(fp); として、問題は無いでしょうか?よろしければご回答お待ちしております。

noname#26650
noname#26650
回答No.3

> No.2さん > printf("%d\n", *data + i); ファイルから読み取ったとおりの内容をprintfするのでしたら、 *(data + i) もしくは data[i] でなければならないはずです。 カッコの有無で意味が全く違いますので。

noname#30991
質問者

お礼

アドバイスありがとうございました。 気づかずに素通りしていましたが、よく考えたらカッコ必要ですね。

  • Tasuke22
  • ベストアンサー率33% (1799/5383)
回答No.1

書き込みと読み出しのどちらがうまくいかないと言っているのか 良く分かりませんが、少なくとも、書いたものを読むのに、区切り がありませんよね。何桁読んでいいのか分からないわけです。 改行を入れて分けてみましょうか。 fprintf( fp, "%d\n", i ); fscanf( fp, "%d\n", data+i ); それからmallocなんて難しい関数は使う必要がないでしょう。 int data[32768]; として、 fscanf( fp, "%d\n", data[i] ); の方がスマートなのでは。

noname#30991
質問者

お礼

さっそくのご回答ありがとうございました。 読み出しがうまくいかなかったのですが、原因はやはり改行を入れていなかったためのようでした。ありがとうございます。

関連するQ&A

  • ファイルの入出力

    学生です。まだ習い始めて間もないのですがよろしくお願いします。 27.000000,207.000000,116.000000 48.000000,90.000000,116.000000 48.000000,90.000000,116.000000       : テキストの中にある上記のカンマ区切りのデータをfscanfで読み込んで違うテキストに同じ数値を出力したいのですがうまく出力できません。 0.000000,0.000000,+NAN 0.000000,0.000000,+NAN 0.000000,0.000000,+NAN      : 数値は上記のように出力されてしまいます。 プログラムは以下の通りです。 main() { FILE *fp; double m[30][3]; int i,j; double e1,e2,e3; fp=fopen("data00.txt","r"); for(i=0;i<30;i++){  fscanf(fp,"%f,%f,%f\n",&e1,&e2,&e3);  m[i][0]=e1;  m[i][1]=e2;  m[i][2]=e3; } fclose(fp); fp=fopen("data01.txt","w"); for(j=0;j<30;j++){  fprintf(fp,"%f,%f,%f\n",m[j][0],m[j][1],m[j][2]); } fclose(fp); getch(); exit(0); } データの読み込みがうまくいってないのだと思いますがわかりません。 間違いがあったならご指摘お願いします。

  • テキストファイルの出力について

    今、学校の課題でC言語を使ってプログラムを作っています。 20000個のデータを読み込んで、200個ずつに区切り、別々のテキストファイルで出力するというものです。 最初につくったのは、以下の通りです。 *********************************************** FILE *fp; { int b,i=0; data[0][i]=trend_data[0][i]; data[1][i]=trend_data[1][i]; fp = fopen("D1.txt","w"); for(i=0;i<=199;i++){ fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); } fclose(fp); fp = fopen("D2.txt","w"); for(i=200;i<=399;i++){ fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); } fclose(fp); ・・・ ***************************************** これだと20000まで繰り返し記述しなければならずかなり困難だと思いました。そこで、ループを作ろうとしたのですが、テキストファイルをループを使って複数作成する方法がわかりません。 以下のようなプログラムを作ったのですが、テキストファイルが一つしか作られませんでした。 どのように記述すればよいのでしょうか? **************************************** FILE *fp; { int a,i=0; int b=1; int c=199; data[0][i]=trend_data[0][i]; data[1][i]=trend_data[1][i]; start: fp = fopen("D[1+b].txt","w"); for(i=a;i<=c;i++){ fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); if(i > c) c = c+200; a = a+200; b++; goto start; fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); fclose(fp); } } ****************************************** よろしくお願い致します。

  • C言語のファイル入出力について

    for文の中でファイルの入出力をファイル名を変えながら行うことはできますか?作成したいプログラムは以下の通りになっています。 よろしくお願いします。 #include<stdio.h> main() { int i; FILE *fp; for(i=0;i<10;i++) {  fp=fopen("ココにiの値を入れたい.txt","w");  fprintf(fp,"%d\n",i);  fclose(fp); } return(0); }

  • 複数テキストファイルを読み込み、複数テキストファイルの出力

    質問は100個のテキストファイル(それぞれ10個のデータを含む)を読み込み、それぞれのテキストファイルから5個ずつデータを抽出し、200個のテキストファイルとして出力するというプログラムについての質問です。 以下が僕の作ったファイル出力部分のプログラムです。 /************/ void ecg_rr(fp,data_max) FILE *fp; { int b,i=0; int c=1; char fname[64]; data[0][i]=trend_data[0][i]; for(i=0;i<100;i++) sprintf(fname,"ss[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][0]); fprintf(fp,"%8.8f\n",data[0][2]); fprintf(fp,"%8.8f\n",data[0][4]); fprintf(fp,"%8.8f\n",data[0][6]); fclose(fp); sprintf(fname,"sk[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][1]); fprintf(fp,"%8.8f\n",data[0][3]); fprintf(fp,"%8.8f\n",data[0][5]); fprintf(fp,"%8.8f\n",data[0][9]); fclose(fp); } 複数ファイルの読み込み方がわからず、自分のプログラムだと1つのテキストファイルしか読み込めないので、16_4.batを作り、その中身を 16_4 読み込むテキストファイル名1.txt ss[1] 16_4 読み込むテキストファイル名1.txt sk[1] 16_4 読み込むテキストファイル名2.txt ss[2] 16_4 読み込むテキストファイル名2.txt sk[2] ・・・ とやったのですが、うまくいきませんでした。 どうすればよいのでしょうか。

  • 複数ファイルの出力

    質問があります。1600個のデータを読み込んで(16個ずつの組で100組)、1番目、3番目、5番目、7番目のデータをss[1].txtとして出力し、同様に2番目、4番目、6番目、8番目のデータをsk[1].txt、9番目、11番目、13番目、15番目のデータをks[1].txt、10番目、12番目、14番目、16番目のデータをkk[1].txtとして出力させます。以下、ss[2].txt,sk[2].txt,ks[2].txt,kk[2].txt・・・に関してはそれぞれ直前のファイルに16を足したデータ(例えばss[2].txtなら、17番目、19番目、21番目、23番目のデータを出力)を出力させるというプログラムです。 以下に自分で作ったプログラムを掲載します。 void ecg_rr(fp,data_max) FILE *fp; { int i,j=0; int c=1; char fname[64]; data[0][i]=trend_data[0][i]; for(i,j=0;i<100,j<100;i++,j++) { sprintf(fname,"ss[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][0+j*16]); fprintf(fp,"%8.8f\n",data[0][2+j*16]); fprintf(fp,"%8.8f\n",data[0][4+j*16]); fprintf(fp,"%8.8f\n",data[0][6+j*16]); sprintf(fname,"sk[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][1+j*16]); fprintf(fp,"%8.8f\n",data[0][3+j*16]); fprintf(fp,"%8.8f\n",data[0][5+j*16]); fprintf(fp,"%8.8f\n",data[0][9+j*16]); fclose(fp); /*ks,kkに関しても同様*/ } } これだと100個ずつファイルを出力できるのですが、データが全て0として出力されてしまいます。

  • ファイルをオープンするときのエラー

    C言語であるファイルにある数値を100ごとに合計して,ほかのファイルに書き出す。しかし,実行するとエラーでてきます。原因はわからないです。因みに,オープンしたいファイルをほかのディレクリに置いたら,ファイルが見付かりませんとのエラーがありました、WindowsのC言語でカレントディレクトリを探すときは何の関数を使えばいいでしょうか? int main(void) { int i,k; int num; char filename[64],fileread[64],filewrite[64]; FILE *fp0,*fp1; double sum1,sum2,sum3; int *ch[3]; sum1=sum2=sum3=0.0; printf("ファイル名を入力ください!\n"); scanf("%s",filename); fprintf(stderr,"\n%s\n",filename); sprintf(fileread,"C:\\%s.txt",filename); fprintf(stderr,"%s\n",fileread); sprintf(filewrite,"C:\\%s.csv",filename); for (i=0;i<3;i++) { if ( (ch[i]=(int *)malloc(4*30))==NULL ) { fprintf(stderr,"Cannot get memory <ch[%d]>.",i); return -1; } } fprintf(stderr,"%s\n",filewrite); if ((fp0=fopen(fileread,"rb"))==NULL) { fprintf(stderr,"Cannot open file %s\n",fileread); return 0; } fscanf(fp0,"%d", &num); if((fp1=fopen(filewrite,"wb"))==NULL) { fprintf(stderr,"Cannot open file!%s\n",filewrite); return 0; } for(i=0;i<50;i++) { fscanf(fp0,"%d %d %d",*(ch[0]),*(ch[1]),*(ch[2])); } for(i=0;i<num/100;i++) { for (k=0;k<100;k++) { fscanf(fp0,"%d %d %d",*(ch[0]),*(ch[1]),*(ch[2])); if ( feof(fp0) != 0 ) break; sum1=sum1+*(ch[0]); sum2=sum2+*(ch[1]); sum3=sum3+*(ch[2]); } fprintf(fp1,"%d %d %d\n",sum1,sum2,sum3); } fclose(fp0); fclose(fp1); return 0; }

  • ファイルに文字列を書く

    ファイルを2つ読み込んでファイルを書き直そうとしたのですが 2度目に書き込もうとしたときに改行の書き込みがおかしくなってしまいます してほしいところで改行を一回だけしてほしいと思っているのですが 実際には多数改行されます どうしたら改行が一回だけになりますか? ---ソース--- #include <stdio.h> void main(void){ FILE *fp; char *tm[1000]; char buf[400]; int i=1,sei; fp= fopen("now.txt","w+"); fprintf(fp,"もも"); fclose(fp); //何で最初に書き込んでるんだ? //という突っ込みがあるでしょうが本当に作りたいプログラムは最初にファイルに書き込まないといけないためです。 fp= fopen("now.txt","r"); while( fgets( buf, 400, fp ) != NULL ){ tm[0]=(char*)malloc(strlen(buf)+1); strcpy(tm[0], buf); } fclose(fp); fp =fopen("moto.txt","r"); while( fgets( buf, 400, fp ) != NULL ){ if(i<999){ tm[i] = (char*)malloc(strlen(buf+1)); strcpy(tm[i], buf); i++; } else{ tm[999] = (char*)malloc(strlen(buf+1)); strcpy(tm[999], buf); } } fclose(fp); if(i<1000){ sei=i; } else{ sei=1000; } fp =fopen("chat_deta.txt","w+"); for(i=0;i<sei;i++){ fprintf(fp,"%s\n",tm[i]); } if(i!=(sei-1)){ fprintf(fp,"\n"); } for(i=0;i<sei;i++){ free(tm[i]); } fclose(fp); } } ---now.txt--- もも ---moto.txt--- オレンジ みかん

  • 構造体でのファイル操作

    1 2 3 1 2 3 1 2 3 1 2 3 みたいに書き込まれた txtデータを構造体でよみこみたいのですけどうまくいきません プログラムはこんなかんじです int i=0; FILE *fp; fp = fopen("Data.txt","r"); while (fscanf(fp, "%d,%d,%d",a.no[i],a.A[i],a.B[i] ) != EOF){ i++; } fclose(fp); a.noが1列目で a.Aが2列目で a.Bが3列目です Debug assertion failed  と表示されます どうしてでしょうか?

  • fscanf関数について

    -------------------------------------------------- #include<stdio.h> #include<stdlib.h> int main() { FILE*fp; int ch,dt; char ss[80]; if((fp=fopen("bbb.txt","w"))==NULL){ printf("出力ファイルをオープンできません.\n"); exit(1); } fprintf(fp,"%c",'A'); fprintf(fp,"%s\n","abcdeABCDE"); fprintf(fp,"%d\n",1234); fclose(fp); if((fp=fopen("bbb.txt","r"))==NULL){ printf("入力ファイルをオープンできません.\n"); exit(1); } ch=fgetc(fp); printf("ch=%c\n",ch); fscanf(fp,"%s",ss); printf("ss=%s\n",ss); fscanf(fp,"%d",&dt); printf("dt=%d\n",dt); fclose(fp); return 0; } -------------------------------------------------- 以上のプログラムで、プログラムの通り「bbb.txt」は、 AabcdeABCDE 1234 となっております。 そこで疑問なのですが、「ch=fgetc(fp);」は1文字読み込みなので、'A'だけと分かるのですが、「fscanf(fp,"%s",ss);」はfpからの読み込みで何故、 AabcdeABCDE 1234 の全部を読み込まず、'A'を抜かした、「abcdeABCDE」だけを読み込んでくれるのか? 後、「fscanf(fp,"%d",&dt);」は何故「AabcdeABCDE」を抜かした、「1234」だけを読み込んでくれるのかが分かりません。 「fscanf(fp,"%d",&dt);」については数値だけを読み込んでくれるのかと思い、 ch=fgetc(fp); printf("ch=%c\n",ch); fscanf(fp,"%s",ss); printf("ss=%s\n",ss); の部分を無くせば、「1234」だけを読み込んでくれるのかと思ったのですが、数値は正しく表示されません。 以上教えていただければ嬉しいです。

  • ファイルの入出力で困っています(C言語)

    はじめまして、nathan3と申します。 昔、さらっとC言語を学んでいたので、仕事場でも活用できればと思い、勉強しなおしています。 以下のプログラムですが、コンパイルはするものの、実行がなされません。 sprintfをつかってファイルを作り、fprintfで読み込み、countで繰り返し別名のファイルを読み込み・作成し…といったプログラムを書いているつもりです。 調べながら書いた稚拙なプログラムですが、ここがちがう!というところをお教えいただけると大変助かります。 #include <stdio.h> int main(void){ FILE *fp,*fo; char *fname1; char *fname2; char s[100],t[100]; int ret,count; for(count = 0 ; count < 3 ; count++) { sprintf(fname1, "sankasha%d.txt", count); fp = fopen(fname1, "r"); if (fp == NULL){ printf("%s can't open a file\n", fname1); return -1; } sprintf(fname2, "matome%d.txt", count); fo = fopen(fname2,"w"); if (fo == NULL){ printf("%s can't open a file\n", fname2); return -1; } printf("--fscanf---"); while( (ret = fscanf(fp,"%[^,],%s", s, t)) != EOF ){ fprintf(fo,"%s ", t); } } fclose(fo); fclose(fp); return 0; } 何度見直しても間違いが見つからず困窮しております。 どうぞ、みなさまのお力をお貸しください! よろしくお願いいたします。

専門家に質問してみよう