- ベストアンサー
C言語でテキストファイルから読み込み
下のような形でデータを保存してあるテキストがあるんですが、このうち四行目以降の6個のデータを読み込んで、別のテキストファイルに書き出したいんです。しかし、四行目以降はまったく同じ書式でかかれているのですが、三行目までが空白だったり、文字が混じっていたりで上手くほしいデータを抽出するコードがかけません。何かいい方法はないでしょうか?ご教授よろしくお願いします。 例) データ番号 1 (スペースはタブ。以下同様。) (空白) (空白) 1.2 2.4 0.0 4.4 3.6 0.0 1.3 2.5 0.0 3.2 2.5 0.0 ・ ・ ・ (以下略)
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
下記でできませんか。 while( (c=fgetc(fp)) != '\n' ) ; /* 1行目 */ while( (c=fgetc(fp)) != '\n' ) ; /* 2行目 */ while( (c=fgetc(fp)) != '\n' ) ; /* 3行目 */ while( ( ret = fscanf( fp, "%lf %lf %lf %lf",&karif1, &karif2, &karif3, &karif4 ) ) != EOF ){ f1=karif1; f2=karif2; f3=karif3; f4=karif4; printf( "%lf %lf %lf %lf¥n",f1, f2, f3, f4 ); }
その他の回答 (5)
- kmee
- ベストアンサー率55% (1857/3366)
fscanf のマニュアル、よくよみましょう。 fscanfでは、改行は基本空白と同じです。 たとえば > fscanf( fp, "%lf %lf %lf %lf",&karif1, &karif2, &karif3, &karif4 ) ですが、"%lf"4つ並べて「1行」読んでるつもりなのでしょうが 1.3 1.3 1.4 1.4 も 1.3 1.3 1.4 1.4 も 1.3 1.3 1.4 1.4 も全部同じに読み込みます。 ・読み書きに同じFILE *を使っている限り、fgetcとかfscanfを混ぜて使っても問題ありません。 fgetcで読んだ後にfscanfを使えば、fgetcで読んだ続きからfscanfが処理されます。 ・行単位で処理したかったら、1行ずつfgets等で読みこんで、その文字列を処理するのが確実です。
お礼
fscamfについて誤解していました。 ファイルポインタや文字の取り扱いについてまた勉強してみたいと思います。 ご回答してくださってありがとうございました。
- samtomsan
- ベストアンサー率55% (1060/1897)
ANo.3です。 最初の三行は個数が同じでないのですね。 ANo.2さんの空読みをしてから whileを実行し、wileの中のif(idt > 2)を止めて四行目からの処理でできませんか。 先にも書きましたように、fgetsを使って行単位で読み込み、最初の三行は無視して四行目からsplitしてデータを一行に含まれる個数に分けてから処理する方が柔軟性があって楽ではないかと思います。
- samtomsan
- ベストアンサー率55% (1060/1897)
空読みはANo.2さんが回答されていますが、お示しの所のように書きたいのでしたら下記でしょうか。 「%lf」か「%f」かはデータと変数の型によります。 while(( ret = fscanf(fp,"%f,%f,%f,%f,%f,%f\n",&kari[0],&kari[1],&kari[2],&kari[3],&kari[4],&kari[5])) != EOF) { // 4行目以降を読み込む if(idt > 2) { ch1[i]=kari[0]; //データ列1つ目 ch2[i]=kari[1]; //データ列2つ目 ch3[i]=kari[2]; //データ列3つ目 ch4[i]=kari[3]; //データ列4つ目 ch5[i]=kari[4]; //データ列5つ目 ch6[i]=kari[5]; //データ列6つ目 } //ループカウンタをインクリメント idt++; // // データ6個の処理 // } fgetsを使ってsplitした方が柔軟性はあると思いますが。
補足
再三申し訳ないのですが、やはりどうもうまくいきませんので、私が作成したコードを見てもらえないでしょうか? と言いますのも、テキストの中身が(例1)だと上手くいくのですが、(例2)だと一行目に文字列が入っている時点でデータの型が一致しないためか、まともな数字が代入されないのです。 よろしくお願いします。 (例1) 1.3 1.3 1.4 1.4 1.3 1.3 1.4 1.4 1.3 1.3 1.4 1.4 1.3 1.3 1.4 1.4 1.3 1.3 1.4 1.4 (例2) a (空白) (空白) 1.3 1.3 1.4 1.4 1.3 1.3 1.4 1.4 1.3 1.3 1.4 1.4 (コード) #include <stdio.h> int main(void) { FILE *fp; char *fname = "space.txt"; int ret; double f1,f2,f3,f4; int idt=0; double karif1,karif2,karif3,karif4; fp = fopen( fname, "r" ); if( fp == NULL ){ printf( "%sファイルが開けません¥n", fname ); return -1; } while( ( ret = fscanf( fp, "%lf %lf %lf %lf",&karif1, &karif2, &karif3, &karif4 ) ) != EOF ){ printf("idt=%d\n",idt); if(idt>2){ f1=karif1; f2=karif2; f3=karif3; f4=karif4; printf( "%lf %lf %lf %lf¥n",f1, f2, f3, f4 ); } idt++; } fclose( fp ); }
- kmee
- ベストアンサー率55% (1857/3366)
なんか、難しく考えすぎてないですか? 例ですが while( (c=fgetc(fp)) != '\n' ) ; /* 1行目 */ while( (c=fgetc(fp)) != '\n' ) ; /* 2行目 */ while( (c=fgetc(fp)) != '\n' ) ; /* 3行目 */ などと3回'\n'が来るまで「読みこむだけ」で、その続きから読めば4行目から読み込めます。 上のをそのまま使うと、行数が変わったり、3行未満だったりすると面倒ですが。
補足
ご回答ありがとうございます。 おっしゃる通り少し難しく考えすぎているのかもしれません。 しかし、ひとつ気になることがあります。 私はテキストファイルを読み込む際、fscanf関数を使用しています。 fscanfはテキストの先頭から読み込むと思うのですが、 だとすると三回¥nを読み込んでから、fsancfで四行目以降を読み込む、という技は 使えないと思うのですが、kmee様が仰っている方法はそもそもfscanfを使用しない方法なのでしょうか? できることならば、なにかコードを追加することでテキストの先頭から三行は飛ばすという命令を加えて、 while( ( ret = fscanf( fp, "%f %f %f %f %f %f",&n1, &n2, &n3, &n4))!= EOF ) といったコードで四行目以降から読み込み開始できればと思っています。
- samtomsan
- ベストアンサー率55% (1060/1897)
どちらが求める回答でしょうか。 > 四行目以降の6個のデータを読み込んで、別のテキストファイルに書き出したいんです 最初の三行は空読みすればすみますね。 > 三行目までが空白だったり、文字が混じっていたりで上手くほしいデータを抽出するコードがかけません 空白を区切りとしてsplitされたらいかがでしょうか。 http://d.hatena.ne.jp/mohayonao/20090227/1235742693
補足
さっそくのご回答ありがとうございます。 4行目以降のデータがほしいのですが、最初の三行をから読みとはどうすればよいのでしょうか? ちなみに私が最初に考えていたのは以下に紹介されている方法でしたので、こちらをベースにできる方法だと理解しやすく非常に助かるのですが・・・。よろしくお願いします。 http://okwave.jp/qa/q6975702.html
お礼
ご回答ありがとうございます。 お陰様で無事読む込むことができました。 何度もお手数おかけして申し訳ありませんでした。 本当にありがとうございました。