Search code examples
c++parsingnumberstext-filestabular

How to parse table of numbers in C++


I need to parse a table of numbers formatted as ascii text. There are 36 space delimited signed integers per line of text and about 3000 lines in the file. The input file is generated by me in Matlab so I could modify the format. On the other hand, I also want to be able to parse the same file in VHDL and so ascii text is about the only format possible.

So far, I have a little program like this that can loop through all the lines of the input file. I just haven't found a way to get individual numbers out of the line. I am not a C++ purest. I would consider fscanf() but 36 numbers is a bit much for that. Please suggest practical ways to get numbers out of a text file.

int main()
{
    string line;
    ifstream myfile("CorrOut.dat");
    if (!myfile.is_open())
        cout << "Unable to open file";
    else{
        while (getline(myfile, line))
        {
            cout << line << '\n';
        }
        myfile.close();
    }
    return 0;
}

Solution

  • Use std::istringstream. Here is an example:

    #include <sstream>
    #include <string>
    #include <fstream>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        string line;
        istringstream strm;
        int num;
        ifstream ifs("YourData");
        while (getline(ifs, line))
        {
            istringstream strm(line);
            while ( strm >> num )
               cout << num << " ";
            cout << "\n";
        }
    }
    

    Live Example

    If you want to create a table, use a std::vector or other suitable container:

    #include <sstream>
    #include <string>
    #include <fstream>
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    int main()
    {
        string line;
    
        // our 2 dimensional table
        vector<vector<int>> table;
    
        istringstream strm;
        int num;
        ifstream ifs("YourData");
        while (getline(ifs, line))
        {
            vector<int> vInt;
            istringstream strm(line);
            while ( strm >> num )
               vInt.push_back(num);
            table.push_back(vInt);
        }
    }
    

    The table vector gets populated, row by row. Note we created an intermediate vector to store each row, and then that row gets added to the table.

    Live Example