IOResult

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

} while (! file.eof());

thanks in advance
Can you give an example of the file you want to read?
example:
1
2
3
4
5
6
7
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:

123 6123 65 876 976 90 98 8
7 76 76 897 90 76 87 49
INF INJ NULL 765 98 76 87 9
....
....
....

2/ then, if whole row contains floats -> assign all cells from that row to array, each cell goes to different variable but same numeral [i]

thanks
How about a loop? You could make a nice function out of the code I posted that takes ifstream& and float&. Then
1
2
3
4
while(!file.eof()){
    for(int col = 0; col < number_of columns; col++) a_nice_function(file, a_nice_array[col+row*number_of_columns]);
    row++;
}
You will always need to check for failure when converting to double... but that need not slow you down much.

1
2
3
4
5
6
#include <algorithm>
#include <cctype>
#include <functional>
#include <iostream>
#include <string>
#include <vector> 
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
45
46
47
48
49
50
51
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.)
    else if (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;
      else if (s == "+INF") d =  1.0/0.0;
      else if (s == "-INF") d = -1.0/0.0;
      else if (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();

And using it is equally simple:

1
2
3
cout << "Number of rows: " << m.size() << "\n";
cout << "Number of columns: " << m[ 0 ].size() << "\n";
cout << "Value at (7, 3): " << m[ 7 ][ 3 ] << "\n";

Hope this helps.
Thank you guys for all the replies.
Topic archived. No new replies allowed.