c++でのプログラミングに関して参考になるページを教えて下さい.

データファイルを読み込んで,配列に代入したいと思います.
例えば,

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.変数の型毎に配列に格納
みたいな事が出来ればと思います.

よろしくお願いします.

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2011/08/29 15:30:03
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:miscellaneousness No.3

回答回数4ベストアンサー獲得回数1

ポイント66pt

ストリームから「>>」演算子で欲しい型の変数に入力すればいいです。

エラー処理なしで書くと、こんな感じ。

#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";
    }
}
id:taki

ありがとうございます.

このソースで読み込めました.

それで,その先なのですが,読み込んだ後に,配列の要素1つ1つを指定するのはどうするのでしょうか?

year[0]とかやってみたのですが,違うみたいですね.

そのあたりも出来ればぜひ教えて下さい.

2011/08/24 08:41:37

その他の回答3件)

id:taknt No.1

回答回数13539ベストアンサー獲得回数1198

ポイント67pt

http://www.mapee.jp/cpp/iostreamfstream.html

少しは参考になると思います。

id:taki

早速ありがとうございます.

このページはすでに見てたのですが,数値とテキストが混在してる場合がイマイチ良く分からないのです.

2011/08/22 16:09:07
id:windofjuly No.2

回答回数2625ベストアンサー獲得回数1149

ポイント67pt

空白で区切られているようなので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(""); は文字列ストリームバッファの内容を削除します。

上記、抜粋部分の続きにもう少し詳しいサンプルがありますので参照してみてください

id:miscellaneousness No.3

回答回数4ベストアンサー獲得回数1ここでベストアンサー

ポイント66pt

ストリームから「>>」演算子で欲しい型の変数に入力すればいいです。

エラー処理なしで書くと、こんな感じ。

#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";
    }
}
id:taki

ありがとうございます.

このソースで読み込めました.

それで,その先なのですが,読み込んだ後に,配列の要素1つ1つを指定するのはどうするのでしょうか?

year[0]とかやってみたのですが,違うみたいですね.

そのあたりも出来ればぜひ教えて下さい.

2011/08/24 08:41:37
id:miscellaneousness No.4

回答回数4ベストアンサー獲得回数1

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";
    }

# シーケンシャルアクセスなら、イテレーターに慣れた方が良いと思います。

id:taki

ありがとうございます.

まだ試していませんが,これをヒントにやってみます.

2011/08/29 19:54:35
  • id:taknt
    読み込みは 最初は すべて 文字で 読んで、その後 文字→数値化してやればいいと思います。
  • id:windofjuly
    うぃんど 2011/08/22 21:29:30
    テスト環境が無く、直接使えるコードを書いていないので、コメント欄にしようかとも思いましたが、ろくな回答やコメントが見当たらないので、あえて回答欄で失礼しました
  • id:a-kuma3
    コメントを書いてる時点で、istream を使った回答しか出て無いので、注意点をひとつ。
    提示されている例を見れば分かると思いますが、桁の指定ができてません。
    最悪の場合、city にあたるところが、全て空白のデータがあると、そこからひとつずつずれます。
    受け取る変数に数値型があれば、エラーがすぐに出るので、すぐに分かりますが。

    後、微妙なのは、以下のデータの 08 。
    2011 08 01 0.1234E-01 TOKYO

    dec の指定が無いと、エラーになりそうな気がする。
  • id:miscellaneousness
    2点とも大丈夫ですよ。

    > 桁の指定ができてません

    1行=1レコード読み込んでから、改めてフィールドを読み込んでいます。

    > dec の指定が無いと、エラーになりそうな気がする

    デフォルトがdecです。
  • id:a-kuma3
    たっはっは、釈迦に説法だったようで > id:miscellaneousness さん

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません