• ベストアンサー

C++で、テキストファイルを一行ずつ読み込んで配列に入れたいのですが、

C++で、テキストファイルを一行ずつ読み込んで配列に入れたいのですが、うまくできません! テキストには -3.0        1.0        2.0 ・・・などのように一行に一つの数値が入って縦に並んでいます。 それをひとつずつ読み込み、新しい配列(たとえばa[])に順番にいれたいのです。 a[1]=-3.0,a[2]=1.0、・・・と なるように。 どうか、この初心者にご指導お願いいたします。

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

  • ベストアンサー
回答No.3

fgetsは文字列として読み込みます。これを数値に変換すれば、とりあえずあなたが望んでいることができます。変換はatofを使います。また、atofを使用するときは#include <stdlib.h>が必要です。 例えば #include <stdlib.h>   : double d;   : d=atof("-3.0"); とすると、文字列の-3.0が数値の-3.0に変換されdに入ります。 fscanf関数で読み込んでもできますが、書式とデータがあっていないと上手くいかないので注意してください。

noname#122223
質問者

お礼

回答ありがとうございます。 先に、補足の方を書いてしまって変更できないようなので、こちらで書かせて頂きます。 fscanをつかって n=3500;/*数値の数*/ fp=fopen("date.txt","r"); for ( i = 0; i < n; i++ ) { fscanf( fp, "%1.5e", &a[ i ] ); } fclose( fp ); として、このあとprintfで、配列a[]を書き出したところ, まったくでたらめな数値が書き出されてしまいました。 忠告頂いた、「書式とデータがあっていない」という状態なのでしょうか?

noname#122223
質問者

補足

回答ありがとうございます。 えっと、つまりは while内で、 { fgets(buffer,size,fp) d=atof("buffer"); } などと行えばいいのでしょうか。 また、この補足を読まれて、もしお時間があれば fscan関数の使い方をお教え願いたいのですが。 ファイル操作関連は、参考書などが曖昧(実際にテキストファイルとその中身を具体的に書いていないため?)で、実際にはどのように使用したら良いのかわかりません。

その他の回答 (5)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

「でたらめ」というだけではわからんので, 「何がどうなったのか」も書いてくれるとありがたいなぁ. ちなみに C++ 的には #include <iostream> #include <iterator> #include <vector> #include <algorithm> という前提のもとで std::ifstream ifs("data.txt"); std::vector<double> data; std::copy(std::istream_iterator<double>(ifs), std::istream_iterator<double>(), std::back_inserter(data)); なのかもしれない.

noname#122223
質問者

お礼

何度も回答ありがとうございます! 「でたらめ」なデータとは、元のテキストファイル内容とはかけ離れた値で、 とんでもなく大きかったり、0でない場所が0になってしまっている状態です。 fscanfでのデータ入力が正しく行われていなかったようです。 やりたかったことは、実現できましたがTacosan にお教え頂いた方法も調べて試してみたいと思います。 本当にありがとうございました。

回答No.5

>fscanをつかって n=3500;/*数値の数*/ fp=fopen("date.txt","r"); for ( i = 0; i < n; i++ ) { fscanf( fp, "%1.5e", &a[ i ] ); } fclose( fp ); として、このあとprintfで、配列a[]を書き出したところ, まったくでたらめな数値が書き出されてしまいました。 忠告頂いた、「書式とデータがあっていない」という状態なのでしょうか? 私自身scanfやfscanfは余り使用しないので詳しくないのですが、以下のプログラムをコピペして実行してみてください。ヒントになりますか? #include <stdio.h> void main(){ float a[3]; FILE *fp; fp=fopen("data01.txt","r"); for(int i=0;i<3;i++){ fscanf( fp, "%e\n", &a[ i ] ); } fclose( fp ); for(int i=0;i<3;i++){ printf("%f\n",a[i]); } } ちなみにdata01.txtの内容は -12.30 12.22 11.12 です。 蛇足かもしれませんが、私がscanf系の関数を使用しない理由は、データ入力を間違えてたとき、正しくない数値が入るだけで、エラーにならないことが多いからです。データ入力を間違えたらエラーにして欲しいので、freadなどを用いて、自分でデータ解析を行い、おかしなデータであれば、直ぐエラーメッセージを出力する方が良い(エラーは早い段階で解った方がよい)と思います。

noname#122223
質問者

お礼

何度も回答頂き、有難うございます! 前回の回答を参考にしまして、以下のように書いたところ無事に読み込み、計算することができました。 FILE *fp; char data[MAXDATASIZE];    if((fp=fopen("date.txt","rt"))==NULL){ /*ファイルを開いて*/ printf("file not open¥n"); exit(1); } int i; double x[データの数分]; for(i=0;i<データの数分;i++){ fgets(data,MAXDATASIZE,fp); x[i]=atof(data); /*文字列として読んだものを数値化*/ } fclose(fp); また、fscanfは頂いたソースを用いて勉強していきたいと思います。 しかし、調べたところcyacya2000さんのおっしゃった理由や、その他都合が悪いことがあるようで、 使われない方が多いようですね。 ほんとうに助かりました!ありがとうございました!

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

本当に配列が必要だとするとあらかじめ大きさがわかっていないとダメなんだけど, そこはいいの? 個人的にはこのフォーマットなら std::vector とか std::istream_iterator 使っちゃうなぁ....

noname#122223
質問者

お礼

何度も回答して頂いて、有難うございます。 みなさんの回答を読み合わせて、無事に読み込むことができました。 FILE *fp; char data[MAXDATASIZE];    if((fp=fopen("date.txt","rt"))==NULL){ /*ファイルを開いて*/ printf("file not open¥n"); exit(1); } int i; double x[データの数分]; for(i=0;i<データの数分;i++){ fgets(data,MAXDATASIZE,fp); x[i]=atof(data); /*文字列として読んだものを数値化*/ } fclose(fp); これで、printfでx[]を書き出したところ、ちゃんと読みこめたようです。 もし、穴がありましたらご指摘お願い致します。

noname#122223
質問者

補足

回答ありがとうございます。 大きさはあらかじめ、分かっている状態です。 数値はそれぞれ、○.○○E00 表記で、データ数3500個です。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

なお, 単に「うまくできない」と書くのではなく「どのように」うまくできないのか, つまり ・期待する結果 ・実際の結果 も書くようにしてください. しかし, 「ただの配列」が本当に必要なのかなぁ?

noname#122223
質問者

お礼

ご指摘頂いた通りですね。 曖昧な聞き方をしてしまい、申し訳ございませんでした。

noname#122223
質問者

補足

ご指摘頂いたので、補足させて頂きます。 ひとつ前の方のところに書いたものとかぶりますが、 whileのループを使って、 fgetsで一行ずつ読みだそうと思い、以下のように行いました。 { fgets(buffer, BUFFER_SIZE, fp); printf("%s",buffer); } printfでの書き出しはできるので、読み込み自体はされているのですが、 それをどう配列に入れれば良いのかが初心者の浅知恵では参考書見てもわかりません。 期待する結果は、質問欄にかいた通り、テキストの値をひとつずつ配列に入れたいです。 また、実はこれ以降の計算部を配列を使って作っていまして、 その配列部を同じプログラム上で入れた数値ではなく、テキストファイルにある数値でおこなったらどういう結果になるのかを見たいのです。 そのために、a[]に入れたい、と。 えっと、つまりプログラムの前半部でとある計算結果の値を順に入れた配列A[]をつくった。 後半部で、その配列を用いて計算するプログラムを組んだ その、配列A[]でなく、すでに別に存在している数値(テキストフォルダ)を読み込んで、 配列B[]にいれ、後半部の計算部をB[]に書き換えて計算を行いたいのです。 テキストフォルダの数値が、どのような計算結果のものなのか分かればいいのですが、 そういう説明はなく、ただ数値が書き込まれているものなので読み込むしか、ないかと・・。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.1

>うまくできません! 途中までは書いてみたのでしょうか。 それでしたら、その途中までのソースを提示したほうが、有用なアドバイスが得られやすいと思いますよ。

noname#122223
質問者

お礼

そうですね。 ご指摘ありがとうございます! 補足の方で、補完させて頂きました。

noname#122223
質問者

補足

ご指摘頂いたので、補足させて頂きます。 途中まで、というのはwhileのループを使って、 fgetsで一行ずつ読みだすところまでです。 { fgets(buffer, BUFFER_SIZE, fp); printf("%s",buffer); } printfでの書き出しはできるので、読み込み自体はされているのですが、 それをどう配列に入れれば良いのかが初心者の浅知恵では参考書見てもわかりません。 buffer=a[i]; なんて、通りませんし・・・。

関連するQ&A