Search code examples
c++ifstreamofstream

Skip reading characters from a data file C++


I have a data file (A.dat) with following format:

Theta = 0.0000        Phi = 0.00000
Theta = 1.0000        Phi = 90.0000
Theta = 2.0000        Phi = 180.0000
Theta = 3.0000        Phi = 360.0000

I want to read the values (only) of theta and phi and store them in a data file (B.dat) like this:

0.0000        0.00000
1.0000        90.0000
2.0000        180.0000
3.0000        360.0000

I tried this :

    int main()
    {

      double C[4][2];

      ifstream fR;
      fR.open("A.dat");
      if (fR.is_open())
        {
          for(int i = 0; i<4; i++)
            fR >> C[i][0] >> C[i][1];  
        }
      else cout << "Unable to open file to read" << endl;
      fR.close();

      ofstream fW;
      fW.open("B.dat");

      for(int i = 0; i<4; i++)
        fW << C[i][0] << '\t' << C[i][1] << endl;

      fW.close();
    }

I get this in B.dat:

0       6.95272e-310
6.95272e-310    6.93208e-310
1.52888e-314    2.07341e-317
2.07271e-317    6.95272e-310

How do I skip reading characters and other things and save only the digits?


Solution

  • I often use std::getline to skip past unwanted data because it allows you to read up to (and past) a specific character (in this case the '='):

    #include <string>
    #include <sstream>
    #include <iomanip>
    #include <iostream>
    
    // pretend file stream
    std::istringstream data(R"(
    Theta = 0.0000        Phi = 0.00000
    Theta = 1.0000        Phi = 90.0000
    Theta = 2.0000        Phi = 180.0000
    Theta = 3.0000        Phi = 360.0000
    )");
    
    int main()
    {
    
        double theta;
        double phi;
        std::string skip; // used to read past unwanted text
    
        // set printing format to 4 decimal places
        std::cout << std::fixed << std::setprecision(4);
    
        while( std::getline(data, skip, '=')
            && data >> theta
            && std::getline(data, skip, '=')
            && data >> phi
        )
        {
            std::cout << '{' << theta << ", " << phi << '}' << '\n';
        }
    }
    

    Output:

    {0.0000, 0.0000}
    {1.0000, 90.0000}
    {2.0000, 180.0000}
    {3.0000, 360.0000}
    

    NOTE:

    I put the reading statements inside the while() condition. This works because reading from a stream returns the stream object and when put into an if() or a while() condition it returns true if the read was successful or false if the read failed.

    So the loop terminates when you run out of data.