Re: Help reading a file and picking out numerical values
Am 06.12.2012 18:16, schrieb mariogreece@googlemail.com:
int main ()
{
ifstream myobject("Model_1.txt");
string line;
if(!myobject.good()) {
cout << " Problem reading Object file! Aborting. ";
}
You're not actually aborting here. Try this instead:
ifstream in("Model_1.txt");
if(!in)
throw std::runtime_error("failed to open file");
Exception handling is important in C++. Put this on your list of
things to learn!
int number_of_lines = 0,counter,i;
while ( getline(myobject, line) ){
++number_of_lines;
}
Instead of reading and counting, and then reading again, you could
have stored the lines in a container, like e.g. std::vector.
myobject.close();
myobject.open("Model_1.txt");
Here's one thing that will come surprising: After the last line is
read, the next getline() will set the "fail" bit in the fstream. These
bits are never(!) reset implicitly, not even when calling
open(). Either you use a second fstream object or you call the
"clear()" function before reusing it.
while(!myobject.eof() )
{
getline(myobject, line);
Above you got the loop right, using while(getline(..)), which you
should use here, too.
if (line.c_str()[0] == 'v')
This should rather be:
if(line[0] == 'v')
but then it doesn't catch empty lines (which I don't think you
considered at all, right?). Therefore:
if(line.empty())
throw std::runtime_error("unexpected empty line in input");
line[0]=' '; // set pointer to 0 at the 1st character found
sscanf(line.c_str(),"%f %f %f",
> &Buffer_float_vector[0],
&Buffer_float_vector[1],
&Buffer_float_vector[2]);
In order to get at a pointer starting at the second character, you
could use "line.c_str() + 1". Don't do that though. C++ offers
stringstreams for parsing instead:
if(line[0] != 'v' && line[0] != 'f')
throw std::runtime_error("invalid leading character in line");
std::stringstream s(line.substr(1));
float f[3];
s >> f[0] >> f[1] >> f[2];
if(!s)
throw std::runtime_error("failed to parse line");
There are three important points here:
* Treat the input as floats, like Frank suggested.
* Read and validate the input, you didn't check the
sscanf()-returnvalue in your code.
* Restrict the scope of temporary variables, this makes your code
easier to read because you see immediately where things are used.
myobject.close();
This doesn't hurt, but is redundant. The fstream is closed automatically
when it goes out of scope.
return 0;
Interestingly, this is also redundant. This is an exception only for
main(), where you are allowed to leave the function without a
returnvalue. I consider it better to make it explicit as you did
though.
Greetings!
Uli
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]