如何在C++中解析数字表

How to parse table of numbers in C++

本文关键字:数字 C++      更新时间:2023-10-16

我需要解析格式化为 ascii 文本的数字表。 每行文本有 36 个空格分隔的有符号整数,文件中大约有 3000 行。 输入文件由我在 Matlab 中生成,因此我可以修改格式。 另一方面,我也希望能够在 VHDL 中解析相同的文件,因此 ascii 文本是唯一可能的格式。

到目前为止,我有一个这样的小程序,可以遍历输入文件的所有行。 我只是还没有找到一种方法来摆脱个别数字。我不是一个C++最纯洁的人。我会考虑 fscanf(),但 36 个数字有点多。请提出从文本文件中获取数字的实用方法。

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;
}

使用 std::istringstream . 下面是一个示例:

#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";
    }
}

现场示例

如果要创建表,请使用std::vector或其他合适的容器:

#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);
    }
}

table向量将逐行填充。 请注意,我们创建了一个中间向量来存储每一行,然后将该行添加到表中。

现场示例

您可以使用几种不同的方法,上面提供的方法可能是其中最快的方法,但是如果您有不同的分隔字符,您可以考虑以下解决方案之一:

第一个解决方案,逐行读取字符串。之后,它使用 find 函数来查找特定分隔符的第一个位置。然后,它会删除读取的数字并继续,直到不再找到分隔符。您可以通过修改分隔符变量值来自定义分隔符。

#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
    string line;
    ifstream myfile("CorrOut.dat");
    string delimiter = " ";
    size_t pos = 0;
    string token;
    vector<vector<int>> data;
    if (!myfile.is_open())
        cout << "Unable to open file";
    else {
        while (getline(myfile, line))
        {
            vector<int> temp;
            pos = 0;
            while ((pos = line.find(delimiter)) != std::string::npos) {
                token = line.substr(0, pos);
                std::cout << token << std::endl;
                line.erase(0, pos + delimiter.length());
                temp.push_back(atoi(token.c_str()));
            }
            data.push_back(temp);
        }
        myfile.close();
    }
    return 0;
}

第二种解决方案使用正则表达式,它不关心分隔符的使用,它将搜索并匹配字符串中找到的任何整数。

#include <iostream>
#include <string>
#include <regex> // The new library introduced in C++ 11
#include <fstream>
using namespace std;
int main()
{
    string line;
    ifstream myfile("CorrOut.dat");
    std::smatch m;
    std::regex e("[-+]?\d+");
    vector<vector<int>> data;
    if (!myfile.is_open())
        cout << "Unable to open file";
    else {
        while (getline(myfile, line))
        {
            vector<int> temp;
            while (regex_search(line, m, e)) {
                for (auto x : m) {
                    std::cout << x.str() << " ";
                    temp.push_back(atoi(x.str().c_str()));
                }
                std::cout << std::endl;
                line = m.suffix().str();
            }
            data.push_back(temp);
        }
        myfile.close();
    }
    return 0;
}