Parsing a file and storing columns as 3-D vector

Hi All,

I have a file that contains 4 columns and wish to take columns 2,3 and 4 for calculation.

N -9.674570 2.215540 -4.211275
HT1 -10.104954 2.712259 -4.987126

I have written a working program for this as follows.
.........
while(!infile.eof())
{
infile >> atom >> x >> y >> z;
{
if(infile.eof())
{
cout << "Finished reading file" << endl;
break;
}
xval.push_back(x);
yval.push_back(y);
zval.push_back(z);
}
}

Now, I wish to store col2, 3 and 4 as a 3D vector and tried to rewrite it as below.

..................
vector <double> xyz;
vector <vector <double> > coord;
infile.open("test1.pdb");
while(!infile.eof())
{
infile >> atom >> x >> y >> z;
{
if(infile.eof())
{
cout << "Finished reading file" << endl;
break;
}
xyz.push_back(x);
xyz.push_back(y);
xyz.push_back(z);
coord.push_back(xyz);
}
}
but I observed the following problem.
The values of x,y and z are stored one after the other yielding thrice the actual number of lines in the file.
Say, number of lines in the file is 100. The second program yielded xyz.size() as 300.

Could somebody let me know how to go about this issue?
I wanted to use coord vector for vector addition and subtraction for further calculations.
Why don't you use a class and store the objects in a vector? Seems easier to me then messing around with nested vectors and single vars.

1
2
3
4
5
6
7
8

class Vector3D
{
  double x, y, z;
};

vector<Vector3D> data;
Hey @Thomas1965,

Thank you for briefing the usage of class.

But I would wish to retain the first column too.. I modified the program using the same old theory and it worked well. Thanks.

Here is my sample code:
ifstream infile;
vector <double> xyz;
vector <vector <double> > coord;

while(!infile.eof())
{
infile >> atom >> x >> y >> z;
xyz.push_back(x);
xyz.push_back(y);
xyz.push_back(z);
coord.pus_back(xyz);
}

The mistake I did was I checked for xyz.size() which is 1-D array while coord.size() which is 2-D array gave the correct size equal to number of lines read.
Last edited on
One piece of advice first. Even if you discard everything else I say.
Please don't use use eof() as the loop condition. (it is not a reliable approach).
Instead, do something like this:
1
2
3
    while (infile >> atom >> x >> y >> z)
    {
        etc.


Now, my suggested code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <fstream>
#include <vector>
#include <string>

class coord3d {
public:
    double x;
    double y;
    double z;
    
    coord3d() : x(0), y(0), z(0) {};
    coord3d(double x1, double y1, double z1) : x(x1), y(y1), z(z1) {};
}; 

int main()
{
    std::vector<coord3d>     points;
    std::vector<std::string> str;
    
    std::ifstream infile("data.txt");
    
    std::string atom;
    double x, y, z;
    
    while (infile >> atom >> x >> y >> z)
    {
        str.push_back(atom);
        points.push_back(coord3d(x,y,z));
    }
    
    for (unsigned int i=0; i<points.size(); i++)
        std::cout << '('  << points[i].x 
                  << ", " << points[i].y 
                  << ", " << points[i].z << ")\n";  

    return 0;
}

(-9.67457, 2.21554, -4.21127)
(-10.105, 2.71226, -4.98713)

You could put the 'atom' as part of the coord3d object too. That way you'd use just a single vector. But it depends what you want.
Last edited on
Topic archived. No new replies allowed.