ここから本文です

c言語 fscanf ループ fscanf関数についての質問です。

c_e********さん

2016/12/1418:49:34

c言語 fscanf ループ

fscanf関数についての質問です。

txt内にたとえば、
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
と記述してあり、forループなどで1から25まで読み込んだあと、もう一度1から25を読み込むことはできるのでしょうか?
できる場合はどのようなプログラムになるか教えていただきたいです。
よろしくお願いします。
自分の考えたプログラムだと25まで読み込んだら、それ以降はずっと21から25を読み込んでしまいます。
以下プログラム
for(i = 0; i < 2; i++){
for(j = 0; j < 5; j++){
switch(j){
case 0:
fscanf(file, "%d %d %d %d %d", &a, &b, &c, &d, &e);
break;
case 1:
fscanf(file, "%d %d %d %d %d", &a, &b, &c, &d, &e);
break;
case 2:
fscanf(file, "%d %d %d %d %d", &a, &b, &c, &d, &e);
break;
case 3:
fscanf(file, "%d %d %d %d %d", &a, &b, &c, &d, &e);
break;
case 4:
fscanf(file, "%d %d %d %d %d", &a, &b, &c, &d, &e);
break;
}
printf("%d %d %d %d %d\n", a, b, c, d, e);
}
}

閲覧数:
219
回答数:
2
お礼:
100枚

違反報告

ベストアンサーに選ばれた回答

hyu********さん

2016/12/1419:15:25

何度も読みたいなら、ファイルのシーク(読み込み位置)をその都度再設定する必要があります。
キーワードは「fseek」「fgetpos」「rewind」等です。詳しくはご自身で調べてください。

以下は、3列x2行の整数が並んだtest.datファイルから、一度6個の値を全て読み込んで表示したのちに、
2行目だけもう一度読み込んで再表示するプログラム例です。

----test.dat-----
1 2 3
4 5 6
-----------------

#include <stdio.h>
#define TATE 2
#define YOKO 3

int main(void) {
FILE *fp = fopen( "test.dat", "r" ) ;
int i, j, tmp ;
fpos_t fpos ;

/* 1回目読み込み */
printf( "1回目読み込み\n" ) ;
for( i = 0 ; i < TATE ; i++ ) {
/* 2行目に入った時のファイル位置を保存 */
if( i == 1 )
fgetpos( fp, &fpos ) ;

for( j = 0 ; j < YOKO ; j++ ) {
fscanf( fp, "%d", &tmp ) ;
printf( "%d ", tmp ) ;
}
printf( "\n" ) ;
}

/* 2行目の位置にファイル位置を戻す */
fseek( fp, fpos, SEEK_SET ) ;

/* 2行目再読み込み */
printf( "2行目再読み込み\n" ) ;
for( j = 0 ; j < YOKO ; j++ ) {
fscanf( fp, "%d", &tmp ) ;
printf( "%d ", tmp ) ;
}
printf( "\n" ) ;


fclose( fp ) ;
return 0 ;
}
------------------
------実行結果------------
1回目読み込み
1 2 3
4 5 6
2行目再読み込み
4 5 6

  • 質問者

    c_e********さん

    2016/12/1510:12:09

    ありがとうございます。
    おしえていただいた関数含め参考にさせていただきます。

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

質問した人からのコメント

2016/12/15 10:17:58

自分のやりたいことに近い回答だったのでこちらをベストアンサーとさせていただきます。
お2人ともありがとうございました。

ベストアンサー以外の回答

1〜1件/1件中

2016/12/1500:14:50

> for(j = 0; j < 5; j++){
> switch(j){
> case 0:
> fscanf(file, "%d %d %d %d %d", &a, &b, &c, &d, &e);
> break;
> case 1:
> fscanf(file, "%d %d %d %d %d", &a, &b, &c, &d, &e);
> break;
<以下略>
そのswitch文、全く無意味。
for(j = 0; j < 5; j++){
fscanf(file, "%d %d %d %d %d", &a, &b, &c, &d, &e);
printf("%d %d %d %d %d\n", a, b, c, d, e);
}
でも、動作はなにも変わらない。
> それ以降はずっと21から25を読み込んでしまいます。
読み込んでいるわけじゃなくて、読み込めなくて値が変わっていないだけ。

で。
ファイル処理としてはrewind()関数を調べてみれば一瞬で解決すると思うけど、
あるいはファイルを全部メモリに読み込んでしまって、後は全部オンメモリで処理する、という考え方もなくはない。

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

char *buff;

char* readFile(char* fname){//ファイルをまるまる読み込んでバッファ先頭へのポインタを返す
FILE *fp;
struct stat statBuf;
long fileSize;
char* ret;

fp=fopen(fname,"r");
if(!fp){
fprintf(stderr,"File open error.\n");
exit(-1);
}
if(fstat(fileno(fp),&statBuf)==-1){//ファイルサイズを求める
fprintf(stderr,"File stat error.\n");
exit(-1);
}
fileSize=statBuf.st_size;
ret=malloc(fileSize);//ファイルサイズ分のメモリを確保
if(!ret){
fprintf(stderr,"Memory error.\n");
exit(-1);
}
fread(ret,1,fileSize,fp);//ファイルを全部読み込む
return ret;
}

int main(void){
char* buf=readFile("test.txt");
int i,j;
for(i=0;i<2;i++){
char* ptr=buf;//データの先頭に処理位置を移す
for(j=0;j<5;j++){
int a,b,c,d,e;
a=strtol(ptr,&ptr,0);//文字列から数値取り出し
b=strtol(ptr,&ptr,0);
c=strtol(ptr,&ptr,0);
d=strtol(ptr,&ptr,0);
e=strtol(ptr,&ptr,0);
printf("a:%d b:%d c:%d d:%d e:%d\n",a,b,c,d,e);
}
printf("\n");
}
free(buf); //確保したメモリ解放
return 0;
}

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる