简体   繁体   中英

Reading formatted numerical data to an array in C++

I am using C++. I have a data file which looks like this with several thousand rows, where the first number is the number of rows.

1238
0.37 0.29 -1.00
1.34 -2.95 3.40
4.59 2.21 1.29

I would like to read it into a two dimensional array.

My code, which works is:

int main(){
    ifstream source("atoms.xyz");
    int N;
    source >> N;
    double atoms[N][3];
    int i = 0;
    for (;i < N; i++){
        int j = 0;
        for (;j < 3; j ++){
        source >> atoms[i][j];
    }
    }
}

Is this idiomatic ? Looking on other stack overflow answers most seem to use "getline" and other string handling functions, but this seems overcomplicated to me.

First, using variable-length arrays in C++ is an extension, not a standard feature. When the number of entries is not known at compile time, using std::vector provides better portability.

If the number of atoms per line is fixed and is small, it is more idiomatic to "unroll" the inner loop, ie to write

source >> atoms[i][0] >> atoms[i][1] >> atoms[i][2];

instead of

for (;j < 3; j ++){
    source >> atoms[i][j];

Here is one way of rewriting this using std::vector<T> and an unrolled loop:

int n;
cin >> n;
vector<array<double,3>> atoms;
for (int i = 0 ; i != n ; i++) {
    array<double,3> data;
    cin >> data[0] >> data[1] >> data[2];
    atoms.push_back(data);
}

Note the use of std::array for the second "dimension". When the size of the dimension is known at compile time, this option is more economical, both in terms of memory size and cache friendliness.

Demo.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM