57

たとえば、外部テキスト ファイルのデータが次のような場合:

45.78   67.90   87
34.89   346     0.98

このテキスト ファイルを読み取って、C++ で各数値を変数に割り当てるにはどうすればよいですか? ifstream を使用すると、テキスト ファイルを開いて最初の番号を変数に割り当てることができますが、スペースの後の次の番号を読み取る方法がわかりません。

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    float a;
    ifstream myfile;
    myfile.open("data.txt");
    myfile >> a;
    cout << a;
    myfile.close();
    system("pause");
    return 0;
}

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    int data[6], a, b, c, d, e, f;
    ifstream myfile;
    myfile.open("a.txt");

    for(int i = 0; i << 6; i++)
        myfile >> data[i];

    myfile.close();
    a = data[0];
    b = data[1];
    c = data[2];
    d = data[3];
    e = data[4];
    f = data[5];
    cout << a << "\t" << b << "\t" << c << "\t" << d << "\t" << e << "\t" << f << "\n";
    system("pause");
    return 0;
}
4

5 に答える 5

84

繰り返す >> ループで読み込みます。

#include <iostream>
#include <fstream>
int main(int argc, char * argv[])
{
    std::fstream myfile("D:\\data.txt", std::ios_base::in);

    float a;
    while (myfile >> a)
    {
        printf("%f ", a);
    }

    getchar();

    return 0;
}

結果:

45.779999 67.900002 87.000000 34.889999 346.000000 0.980000

ファイルに含まれる要素の数が正確にわかっている場合は、 >> 演算子を連鎖できます。

int main(int argc, char * argv[])
{
    std::fstream myfile("D:\\data.txt", std::ios_base::in);

    float a, b, c, d, e, f;

    myfile >> a >> b >> c >> d >> e >> f;

    printf("%f\t%f\t%f\t%f\t%f\t%f\n", a, b, c, d, e, f);

    getchar();

    return 0;
}

編集:主な質問のコメントに応えて。

2 つのオプションがあります。

  • 前のコードをループ (または 2 つのループ) で実行し、定義された数の値を破棄できます。たとえば、ポイント (97, 60) の値が必要な場合は、5996 (= 60 * 100 + 96 ) 値を取得し、最後の値を使用します。これは、指定された値のみに関心がある場合に機能します。
  • Jerry Coffinが提案したように、データを配列にロードできます。彼はすでにあなたに非常に素晴らしいクラスを提供してくれました。これで問題は解決します。または、単純な配列を使用してデータを格納することもできます。

編集:ファイル内の値をスキップする方法

1234 番目の値を選択するには、次のコードを使用します。

int skipped = 1233;
for (int i = 0; i < skipped; i++)
{
    float tmp;
    myfile >> tmp;
}
myfile >> value;
于 2013-01-25T07:16:39.280 に答える
9

特に、ファイルの各行に同じ数の項目があるかどうかによって異なります。もしそうなら、おそらく次のようなある種の 2D 行列クラスが必要になるでしょう:

class array2D { 
    std::vector<double> data;
    size_t columns;
public:
    array2D(size_t x, size_t y) : columns(x), data(x*y) {}

    double &operator(size_t x, size_t y) {
       return data[y*columns+x];
    }
};

書かれているように、これは必要なサイズを事前に知っていることを前提としていることに注意してください。これは回避できますが、コードは少し大きく複雑になります。

いずれにせよ、数値を読み取って元の構造を維持するには、通常、一度に 1 行ずつ文字列に読み取ってから、stringstream を使用してその行から数値を読み取ります。これにより、各行のデータを配列の個別の行に格納できます。

事前にサイズがわからない場合、または (特に) 異なる行に同じ数の数値が含まれていない可能性がある場合:

11 12 13
23 34 56 78

代わりにa を使用することもできますstd::vector<std::vector<double> >。これはいくらかのオーバーヘッドを課しますが、異なる行のサイズが異なる場合は、ジョブを実行する簡単な方法です。

std::vector<std::vector<double> > numbers;

std::string temp;

while (std::getline(infile, temp)) {
    std::istringstream buffer(temp);
    std::vector<double> line((std::istream_iterator<double>(buffer)),
                             std::istream_iterator<double>());

    numbers.push_back(line);
}

...または、最新の (C++11) コンパイラを使用すると、lineの初期化に括弧を使用できます。

    std::vector<double> line{std::istream_iterator<double>(buffer),
                             std::istream_iterator<double>()};
于 2013-01-25T07:23:04.067 に答える
7

数値の入力演算子は先頭の空白をスキップするため、ループ内で数値を読み取ることができます。

while (myfile >> a)
{
    // ...
}
于 2013-01-25T07:01:19.643 に答える
3

他の人と同じように、別々に読み書きできます。しかし、同じものに書き込みたい場合は、これを試すことができます:

#include <iostream>
#include <fstream>

using namespace std;

int main() {

    double data[size of your data];

    std::ifstream input("file.txt");

    for (int i = 0; i < size of your data; i++) {
        input >> data[i];
        std::cout<< data[i]<<std::endl;
        }

}
于 2015-02-04T01:37:55.703 に答える