Pupulating 3d array from three column data file

Hi all,

I have a text file with three columns like so:

4.556663 238.047684 0
77.605812 268.392334 0
152.255829 256.117035 0
161.680557 252.263550 0
164.127808 242.561691 0
182.847580 246.922028 0
269.891937 255.048630 0
270.984741 269.790710 0
341.515778 282.389130 1
342.871857 165.475021 1
346.616577 113.180603 1
347.114807 157.957321 1
347.226440 96.288391 1
352.038086 124.756363 1
356.248016 143.140244 1
358.461029 112.915352 1
359.709747 95.938019 1
361.811859 134.063004 1
365.368073 144.638123 1
369.964783 249.264877 1
465.875763 97.651413 1
472.213165 83.915527 1
471.711151 108.463486 1
481.405212 67.733902 1
483.801788 43.680492 1
325.779877 159.567505 2
326.435486 144.745926 2
330.326447 101.092079 2
332.505646 114.786072 2
335.738464 149.102417 2
334.349335 221.279617 2
337.242126 294.531708 2
338.136688 131.500198 2
339.230713 236.219131 2
346.559753 112.237541 2
343.074493 166.948975 2

I want read in the data and populate a three dimensional matrix with these columns, with the first column in the first element, the second column in the second element and the third column in the third element.

There are only 3 columns but there are lot of rows, which I may not always know in advance.

The data in the file is in (x,y,z) format so I want to use a 3d array since the third column designates data from the same z plane. Eventually I want to compare x and y values across these data sets.

I don't have much of an idea on where to start and I'm a newb so any help is appreciated.

thanks


Simply create an input file stream and read each value one at a time. Then convert each value as you encounter it to its numerical value (double).

If you have never used file streams, read:

http://cplusplus.com/doc/tutorial/files/

Below is a short example. It's up to you to handle the values, but here's how you would read them from your input file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//Create input stream (handles formatted input by default)
std::ifstream input;

//Open your file
input.open("TextFile1.txt");

//Create string to hold text values
std::string str;

//Retrieve each value from the input stream until EOF reached
while (input >> str)
{
    //... convert the text to a double-precision value...

    //... add value to your container ...
}

//Close the input file
input.close();

//... rest of your program ... 


By default, ifstreams will handle formatted text. This means that values separated by whitespace (spaces, tabs, newlines) are automatically considered separate values. The loop continues until the end of the file is reached, so you don't need to know the number of entries ahead of time. This example omits error checking.

If you need help with conversion from text to double-precision, look into the functions atof() and strtod() - I prefer the latter because you can do some error-checking using it.

Typically, programmers define our own container to handle 3d point or vector types. It's very simple. For example, you could define a struct:

1
2
3
4
5
6
typedef struct
{
    double x;
    double y;
    double z;
} Point3D;


That's just one example out of the many ways programmers handle 3d points. Use whatever suits you. Then you can store your point containers in an array. Since you don't know the number of elements ahead of time, look into using std::vector as your container:

http://cplusplus.com/reference/stl/vector/
Last edited on
Thanks for the reply, what you said makes sense but I never got to the point of learning about the use of the double colon thing (::). Are there analogous functions in less sophisticated terms?
Following your advice and other threads, I was able to piece this code together:

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
39
40
41
42
43
44
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>

using namespace std;


struct Point
{

  double x, y, z;

};

int main()
{

  vector<Point> points;

  ifstream fin("all.txt");

  string str;

  while( getline(fin,str) )
    {

      Point p;

      sscanf( str.c_str(), "%lf %lf %lf\n", &p.x, &p.y, &p.z);

      points.push_back(p);



    }


  cout << "point 1(x,y,z): " << points[10].x << " " << points[10].y << " " << points[10].z << "\n";



}


thanks again!
I was thinking along similar lines ...

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
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;


class Point {
public:
	Point() {x=0; y=0; z=0;};
	~Point(void) {};
	void setFields(const double &xx, const double &yy, const double &zz) {x=xx; y=yy; z=zz;};
	void operator() (Point p) {cout<<"("<<x<<","<<y<<","<<z<<")"<<endl;};	// Function object
private:
	double x, y, z;
};


int main()
{
	double x, y, z;
	Point p;
	vector<Point> pa;
	ifstream fin("points.txt");
	if(fin.good()) {
		while(!fin.eof()) {
			fin >> x >> y >> z;
			p.setFields(x,y,z);
			pa.push_back(p);
		}
		fin.close();
	}
	for_each(pa.begin(), pa.end(), p);	// Print 
	return 0;
}

Sorry... I should have explained that.

The "::" is called the scope resolution operator - it tells which namespace the objects and methods you're using come from. Using different namespaces avoids conflicts when two things share the same name. The statement:

 
using namespace std;


Just makes sure that the compiler looks for that namespace EVERYWHERE it encounters something outside the current context. If you don't use the above statement, you must qualify each object first by doing this:

 
namespace::object_type myObject;


Name conflicts are almost never going to pop up in a small program like yours, but some programmers prefer not to use the "using" statement at all, or at least only in specific areas of their source code. For example, that statement would lead to unexpected results if two namespaces have objects and/or methods with the same name, but you specifically DIDN'T intend to call the std:: version.

Thorough explanation at:

http://www.cplusplus.com/doc/tutorial/namespaces/
Topic archived. No new replies allowed.