I have a text file containing three columns of numbers; one column each for the x,y,z
coordinates of a bunch of points. All numbers are between 0
and 1
.
I have created the following structure:
typedef struct
{
double xcd, ycd, zcd;
} point;
I want to create a size-N array of structures of type point
. Then I want to scan the text file line by line and for the n
th particle, I want to put in the three numbers on the n
th line int开发者_JAVA技巧o the respective xcd
, ycd
and zcd
positions.
Tell me if there is some efficeint way of going about this.
Simply do it like has been shown five million billion kajillion times before, using ifstream
, vector
and various other accouterments.
ifstream infile("myfile.txt");
// check if file opened successfully
if (!infile) {
cerr << "failure, can't open file" << endl;
cin.get();
return EXIT_FAILURE;
}
// the container in which we will store all the points
vector<point> points;
// a temporary point to hold the three coords in while we read them all
point tmp;
// read in three doubles from infile into the three coords in tmp
while (infile >> tmp.xcd && infile >> tmp.ycd && infile >> tmp.zcd)
// add a copy of tmp to points
points.push_back(tmp);
This will read in three doubles and put them in a point
then put a copy of that point
in points
. However, if the number of numbers in the file modulus 3 is not 0, it will stop and not add the incomplete point to points
.
Use a std::fstream
.
If you're sure that the file is correct:
struct Point {
double xcd, ycd, zcd;
};
// btw this is how you should declare a structure in C++,
// the way you shown is rather characteristic to C and only used there
Point tab[N];
void foo() {
std::ifstream f("file.txt");
for (int i=0; i<N; ++i) {
f >> tab[i].xcd >> tab[i].ycd >> tab[i].zcd;
}
}
If you're not sure that the file will exist and contain exactly this number of particles, you should check for f.fail()
after each a read attempt.
I prefer using the standard generic algorithms to writing my own loops:
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <fstream>
typedef struct
{
double xcd, ycd, zcd;
} point;
std::istream& operator>>(std::istream&is, point& pt)
{
return is >> pt.xcd >> pt.ycd >> pt.zcd;
}
int main(int ac, char **av) {
std::ifstream f("file.txt");
std::vector<point> v;
std::copy(
std::istream_iterator<point>(f),
std::istream_iterator<point>(),
std::back_inserter(v));
}
Another design is to overload the stream extraction operator in your point structure:
struct Point
{
double x;
double y;
double z;
friend istream& operator>>(istream& inp, Point& p);
}
istream& operator>>(istream& inp, Point& p)
{
inp >> x;
inp >> y;
inp >> z;
inp.ignore(100000, '\n');
return inp;
}
Usage:
ifstream myfile("data.txt");
Point p;
vector<Point> point_container;
while (myfile >> p)
{
point_container.push_back(p);
}
精彩评论