データファイルを読み込んで,配列に代入したいと思います.
例えば,
2011 08 01 0.1234E-01 TOKYO
2011 08 01 0.4567E-01 OSAKA
.
.
というようなデータファイルがあるとすると,
fortranでは,
read(10,'(i4,i3.2,i3.2,e11.4,1x,a5)') ((ymd(i,j),j=1,3),dat(i),city(i),i=1,2)
な感じで読み込めると思うのですが,
c++だとどのようにするのでしょうか?
いろいろな方法があると思いますが,
1.データファイルのサイズを取得し
2.ファイル全体をメモリに読み込み
3.データを解析
4.変数の型毎に配列に格納
みたいな事が出来ればと思います.
よろしくお願いします.
ストリームから「>>」演算子で欲しい型の変数に入力すればいいです。
エラー処理なしで書くと、こんな感じ。
#include <fstream> #include <string> #include <sstream> #include <vector> #include <iostream> struct Record { unsigned short year; unsigned short month; unsigned short day; double d; std::string place; }; int main(int argc, char *argv[]) { std::ifstream file(argv[1]); std::string line; std::vector<Record> records; while ( getline(file, line) ) { std::istringstream istream(line); Record r; istream >> r.year >> r.month >> r.day >> r.d >> r.place; records.push_back(r); } for ( std::vector<Record>::const_iterator iter = records.begin(); iter != records.end(); ++iter ) { std::cout << iter->year << "," << iter->month << "," << iter->day << "," << iter->d << "," << iter->place << "\n"; } }
早速ありがとうございます.
このページはすでに見てたのですが,数値とテキストが混在してる場合がイマイチ良く分からないのです.
空白で区切られているようなのでistringstreamを使えば比較的簡単にできそうです
http://www.sesco.ne.jp/cgi-bin/cdoc?txt=cppprim3#%95%B6%8E%9A%97%F1%83X%83g%83%8A%81[%83%80
#
文字列ストリーム
文字列ストリームはストリームバッファのみで入出力装置には接続していません。 文字列ストリームを利用するには#include <sstream>によりsstreamヘッダファイルを読み込む必要があります。 istringstreamを使って文字列を数値へ変換したり、ostringstreamを使い複数のデータ型を文字列に変換が容易にできます。
例えば以下の通り
int i ;
double d ;
char c;
string s ;
istringstream prein(string( "1 3.14 a PreInput") );
prein >> i >> d >> c >> s;
ostringstream buf;
buf << "PleaseInPutLikeThis " << i << " " << d << " " << c << " " << s << endl;
cout << buf.str( );
文字列ストリームへの参照は、関数 str( ); を使います。
# str( ); は文字列ストリームの文字列を返します。
# str(string); は文字列ストリームバッファへstringを設定します。
# str(""); は文字列ストリームバッファの内容を削除します。
上記、抜粋部分の続きにもう少し詳しいサンプルがありますので参照してみてください
ストリームから「>>」演算子で欲しい型の変数に入力すればいいです。
エラー処理なしで書くと、こんな感じ。
#include <fstream> #include <string> #include <sstream> #include <vector> #include <iostream> struct Record { unsigned short year; unsigned short month; unsigned short day; double d; std::string place; }; int main(int argc, char *argv[]) { std::ifstream file(argv[1]); std::string line; std::vector<Record> records; while ( getline(file, line) ) { std::istringstream istream(line); Record r; istream >> r.year >> r.month >> r.day >> r.d >> r.place; records.push_back(r); } for ( std::vector<Record>::const_iterator iter = records.begin(); iter != records.end(); ++iter ) { std::cout << iter->year << "," << iter->month << "," << iter->day << "," << iter->d << "," << iter->place << "\n"; } }
ありがとうございます.
このソースで読み込めました.
それで,その先なのですが,読み込んだ後に,配列の要素1つ1つを指定するのはどうするのでしょうか?
year[0]とかやってみたのですが,違うみたいですね.
そのあたりも出来ればぜひ教えて下さい.
takiさんのFortranコードと違って、1レコード=1要素で配列にしていますので、添え字でアクセスするなら「records[0].year」のように書きます。
for ( std::vector<Record>::size_type i = 0; i < records.size(); ++i ) { std::cout << records[i].year << "," << records[i].month << "," << records[i].day << "," << records[i].d << "," << records[i].place << "\n"; }
# シーケンシャルアクセスなら、イテレーターに慣れた方が良いと思います。
ありがとうございます.
まだ試していませんが,これをヒントにやってみます.
ありがとうございます.
このソースで読み込めました.
それで,その先なのですが,読み込んだ後に,配列の要素1つ1つを指定するのはどうするのでしょうか?
year[0]とかやってみたのですが,違うみたいですね.
そのあたりも出来ればぜひ教えて下さい.