Parsing a file and storing columns as 3-D vector

Dec 11, 2015 at 1:57pm
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.
Dec 11, 2015 at 6:59pm
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;
Dec 12, 2015 at 10:19am
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 Dec 12, 2015 at 10:23am
Dec 12, 2015 at 11:55am
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 Dec 12, 2015 at 10:02pm
Topic archived. No new replies allowed.