Reading from a text file

Hello there,

It is Ubuntu 14.04 with g++14

I need to read from a text file. I am posting a few first lines:

1
2
3
4
5
6
7
8
9
!# The file contains calculations of the flat areas for the ALP's
 !# L-index  M-index  Angle (deg)
    1       0           0.21
    1       1           8.17
    2       0           0.63
    2       1           3.39
    2       2          15.83
    3       0           0.36
    3       1           4.13


This is a subroutine that does not work:

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
public : void readFlatAreas (int ll, double * flatAreas)
  {
    ifstream myFile;
    int ll1, mm1, ii;
    char *liner;
    double val;
    liner = (char*)std::malloc(100*sizeof(char)); 
    myFile.open ("flatAreas.dat",ios::out);
    myFile.seekg(0, ios::beg);
    myFile >> *liner;
    myFile >> *liner;
    ll1 = -100; 
    while (ll1 != ll)
    {
      myFile >> ll1 >> mm1 >> val;
      if (ll1 == ll)
      {
        ii = -1;
        while (ll1 == ll && !myFile.eof())
        {
          ii += 1;
          flatAreas[ii] = val;
          myFile >> ll1 >> mm1 >> val;
        }
        myFile.close();
        return;
      } 
    }      


The intent is to read lines corresponding to separate indexes L and M and store the value val in an array flatAreas. Something is wrong with the code. Everything compiles. I use gdb to step through it and can see that there is no reading. Please help.

Thanks, - Alex
Last edited on
Are the L-M pairs unique?

Malloc? Why? The istream has ignore() for skipping (e.g. a comment line)
See http://www.cplusplus.com/reference/istream/istream/ignore/

What does the ios::out do for std::ifstream?

"public :" A member function?

Plain C-style array for flatAreas? C++ Standard Library has simple and safe containers.


It is hard to figure out what your loops attempt to do. I do presume that you want to read only the lines, where the L-index equals 'll' (which is a horrid name in the company of ii and ll1).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::vector<std::pair<int,double> foo( int bar,  std::string name ) {
  std::vector<std::pair<int,double>> values;
  std::ifstream file( name );
  file.ignore( 256, '\n' );
  file.ignore( 256, '\n' );
  int il;
  int im;
  double val;
  while ( file >> il >> im >> val ) {
    if ( bar == il ) {
      values.emplace_back( im, val );
    }
  }
  return values;
}
Thank you keskiverto. - Alex
Keskiverto, before I closed the topic I need to ask you a question. First this: I had to modify your code and get rid of the vector. Logically I don't have to retrieve M index. I know it varies from 0 to L-index anyway, thus the position in the array will determine M. So, I changed your code a little bit and it works well. Here it is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public : void readFlatAreas_2 (int bar, double * vedro)
  {
    std::ifstream file ("flatAreas.dat");    
    int il, im, jj=-1;
    double val;
    file.ignore (256, '\n');
    file.ignore (256, '\n');
    bool started = false;
    while ( file >> il >> im >> val ) 
    {
      if ( bar == il ) 
      {
        started = true;
        jj++;
        *(vedro + jj) = val;
      }  
      if (started && bar != il)
        break;    
    } 
    return; 
  } 


This is the code I will most likely use, however, you intrigued me with the vector class (template?) and your code also worked. It is here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public : void readFlatAreas (int bar, std::vector<std::pair<int,double>> values)
  {
    std::ifstream file ("flatAreas.dat");    
    int il, im;
    double val;
    file.ignore (256, '\n');
    file.ignore (256, '\n');
    bool started = false;
    while ( file >> il >> im >> val ) 
    {
      if ( bar == il ) 
      {
        started = true;
        values.emplace_back( im, val );
      }  
      if (started && bar != il)
        break;    
    } 
    return;         
  }


However the problem for me is that I don't know how to retrieve individual values in the calling function. Anything I tried does not compile. For example:

1
2
3
4
5
6
7
8
9
10
public : void checkFlatAreas (int ll)
  {  
     RealWork rw;
     std::vector<std::pair<int,double>> values;
     rw.readFlatAreas (ll, values);
     for (int jj = 0; jj <= ll; jj++)
       {
         std::cout << "jj = " << jj << values[jj] << jj << endl;   // <== Compile error
       }
  }


I will appreciate if you explain to me how I can get my values back. I may use vectors in other applications. Thanks, - Alex
Last edited on
My function creates and returns a copy of a vector object.

Your function takes a vector object argument by value.
The function fills the copy with data, but the copy is destroyed when the function exits.

In order for a function argument to serve as output, it should be by reference.
(Well, your other version has pointer, but you don't touch the pointer itself, just the dereferenced data.)

void readFlatAreas (int bar, std::vector<std::pair<int,double>> & values)


As to the compile error, do note that an element in vector 'values' has type std::pair<int,double>.
Now you would jump to the manual http://www.cplusplus.com/reference/utility/pair/pair/
An element in values has thus two member variables: first and second.


However, if you don't need the M, because it is implicitly in the element's index, then the vector does not need to store a pair. it can store plain double's instead.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void readFlatAreas (int bar, std::vector<double> & values)
  {
    std::ifstream file ("flatAreas.dat");    
    int il, im;
    double val;
    file.ignore (256, '\n');
    file.ignore (256, '\n');
    bool started = false;
    while ( file >> il >> im >> val ) 
    {
      if ( bar == il ) 
      {
        started = true;
        // assert( values.size() == im );
        values.emplace_back( val );
      }  
      if (started && bar != il)
        break;    
    } 
    return;         
  }

http://www.cplusplus.com/reference/cassert/assert/
Thank you very much. I highly appreciate your help. - Alex
Topic archived. No new replies allowed.