C++でフォーマットが決まっているファイルからistringstreamを使ってデータを読み込む

C++でファイルを読み込む方法です。
今回は特にフォーマットが決まったファイルからistringstreamを使ってデータを取得する方法を紹介します。

まずistringstreamを使うと、リダイレクション記号(>>)で文字列から簡単に数値を取り出すことができます。
数値はスペースで区切られている必要があります。

double num1, num2, num3;
istringstream iss("1 2.5 3");
iss >> num1 >> num2 >> num3;
//num1=1, num2=2.5, num3=3 になる

これを応用して、ファイルからデータを読み込む時も、最初にgetline等でファイルから取得した文字列をistringstreamに代入し、最後に上で示したリダイレクション記号を使って数値を取り出します。

ifstream ifs("data.dat");
string str;
double num1, num2, num3;
while (getline(ifs, str)) {
    istringstream iss(str);
    iss >> num1 >> num2 >> num3;
    //data.datから読み込んだ1行が「1 2.5 3」とすると
    //num1=1, num2=2.5, num3=3 になる
}

ただし、この方法はフォーマットが決まっていることが前提なのでそれだけ注意してください。

今回の例では、読み込むファイル(data.dat)はカンマで区切られた3つの数字が1行に格納されていることを想定します。
カンマで区切られているので、今回紹介した方法を使えるようにするために、最初にカンマをスペースに置換します。
置換はstd::replaceで行います。

#include <iostream>
#include <string>
#include <fstream> //for ifstream
#include <sstream> //for istringstream
#include <algorithm> //for replace
 
using namespace std;
 
int main() {
    ifstream ifs("data.dat");
    string str;
    double num1, num2, num3;
 
    while (getline(ifs, str)) {
        replace(str.begin(), str.end(), ',', ' ');
 
        istringstream iss(str);
        iss >> num1 >> num2 >> num3;
        cout << "num1=" << num1 << ", num2=" << num2 << ", num3=" << num3<< endl;
    }
 
    return 0;
}

data.datの中身が以下のようだと

1,5,1.1
-1,3,3.4
2,4,-4.5
10,2,1.08

出力結果は以下のようになります。

num1=1, num2=5, num3=1.1
num1=-1, num2=3, num3=3.4
num1=2, num2=4, num3=-4.5
num1=10, num2=2, num3=1.08

整数でも小数でも負数でも想定通りに動きます。