Reputation: 58
I have a file with data formatted as follows:
a 1.000 -1.000 1.000
b 7.89 4.56 2.46
c 50 20 10
I started writing some code to parse the file and store the data in a vector of structs, but I'm unsure of how to finish this.
struct Coordinates
{
double x;
double y;
double z;
}
vector<Coordinates> aVec;
vector<Coordinates> bVec;
vector<Coordinates> cVec;
ifstream exampleFile;
exampleFile.open("example.txt");
// parse file
while(getline(exampleFile, str))
{
if(str[0] == "a")
{
Coordinates temp;
temp.x = firstNum; // this is where I'm stuck
temp.y = secondNum;
temp.z = thirdNum;
vertVec.push_back(temp);
}
if(str[0] == "b")
{
Coordinates temp;
temp.x = firstNum;
temp.y = secondNum;
temp.z = thirdNum;
vertVec.push_back(temp);
}
if(str[0] == "c")
{
Coordinates temp;
temp.x = firstNum;
temp.y = secondNum;
temp.z = thirdNum;
vertVec.push_back(temp);
}
}
Upvotes: 0
Views: 1034
Reputation: 264351
First of all note that files are represented as streams.
A stream is just something you can read from. So you need to write stream operators for your structures so they can be read.
std::ifstream file("Data"); // This represents a file as a stream
std::cin // This is a stream object that represents
// standard input (usually the keyboard)
They both inherit from std::istream
. So they both act the same when passed to functions that use streams.
int value;
std::cin >> value; // The >> operator reads from a stream into a value.
First write the structure so it knows how to read itself from a stream.
struct Coordinates
{
double x;
double y;
double z;
// This is an input function that knows how to read 3
// numbers from the input stream into the object.
friend std::istream& operator>>(std::istream& str, Coordinates& data)
{
return str >> data.x >> data.y >> data.z;
}
}
Now write some code that reads objects of type Coordinate.
int main()
{
// Even if you only have a/b/c using a map to represent these
// values is better than having three different vectors
// as you can programmatically refer to the different vectors
std::map<char, std::vector<Coordinates>> allVectors;
char type;
Coordinates value;
// Read from the stream in a loop.
// Read the type (a/b/c)
// Read a value (type Coordinates)
while(std::cin >> type >> value)
{
// If both reads worked then
// select the vector you want and add the value to it.
allVectors[type].push_back(value);
}
}
Upvotes: 1
Reputation: 206567
Instead of using
if(str[0] == "a")
{
Coordinates temp;
temp.x = firstNum; // this is where I'm stuck
temp.y = secondNum;
temp.z = thirdNum;
vertVec.push_back(temp);
}
use the following:
// Construct a istringstream from the line and extract the data from it
std::istringstream istr(str);
char token;
Coordinates temp;
if ( istr >> token >> temp.x >> temp.y >> temp.z )
{
// Use the data only if the extractions successful.
if ( token == 'a' ) // Please note that it's not "a"
{
// Do the right thing for a
}
// Add other clauses.
}
else
{
// Deal with the error.
}
Upvotes: 0