Hi Folks,
I am new here. Trying to read three columns of doubles from a file. Unluckily, a file can contain strings instead of doubles and I want to make my code insensitive to this. I know that in Pascal there is IOResult and {$I-},{$I+} to not crush on conversation to assigned variable type. So I expect to arrive with something like:
do
{
here goes: read three columns, if float found then write on std output BUT if not "float" found then not crush and go to the next line
float f;
if(! (file >> f)){//float could not be read (which means there's a string)
string str;
file.clear();//you must clear the error flags before reading again
file >> str;
cout << "I'm a string " << srt << "!\n";
}else cout << "I'm a float " << f << "!\n";
ok guys,
the above solution by hamsterman works great.
However, in case of very many columns it is getting annoying to check each cell with the above "if" statement. I guess, there must be some squeezed way. Let make me clear what I want to do:
1/ read file, like:
typedef vector <double> record_t;
typedef vector <record_t> record_list_t;
//-----------------------------------------------------------------------------
istream& operator >> ( istream& ins, record_t& record )
{
// Get the entire line == one record
string s;
getline( ins, s );
// Break the line up into a proper record_t (which is a list of doubles)
istringstream ss( s );
while (!ss.eof())
{
double d;
if (ss >> d)
record.push_back( d );
// If the usual string-to-double conversion failed, we'll take appropriate
// action to convert the string into the proper double value
// (Notice, again, that this is an exceptional condition, so besides the
// simple stream state check, there is no computational overhead.)
elseif (ss.fail())
{
ss.clear();
ss >> s;
transform( s.begin(), s.end(), s.begin(), ptr_fun <int, int> ( toupper ) );
if (s == "INF") d = 1.0/0.0;
elseif (s == "+INF") d = 1.0/0.0;
elseif (s == "-INF") d = -1.0/0.0;
elseif (s == "NULL") d = 0.0;
// ...other cases go here, such as the unknown "INJ" value you have above...
else /* NAN */ d = 0.0/0.0;
// Finally, we'll append the newly read and converted double to the end of the list
record.push_back( d );
}
}
// As always, return the argument stream
return ins;
}
//-----------------------------------------------------------------------------
istream& operator >> ( istream& ins, record_list_t& records )
{
record_t record;
while (ins >> record)
records.push_back( record );
return ins;
}
Loading your file is simple enough then:
1 2 3 4 5
record_list_t m;
ifstream f( "bar.txt" );
f >> m;
if (!f.eof()) fooey();
f.close();