通过C 通过文本文件解析

Parsing through text file with C++

本文关键字:文件 文本 通过      更新时间:2023-10-16

我正在尝试找出从文本文件中读取数字并将这些数字设置为变量的最佳方法。我很麻烦,因为将有多个文本文件测试我的代码,并且它们的长度和尺寸都不同。样本测试看起来像这样:

0 (1,3) (3,5)
1 (2,6)
2 (4,2)
3 (1,1) (2,4) (4,6)
4 (0,3) (2,7)

第一个数字代表图表上的顶点,坐标中的第一个数字是它在有向图中要朝向的顶点,第二个数字是边缘的重量。我尝试执行getline并将其放入数组中,但是在某些测试用例中可能有100个坐标,我不确定如何指定数组大小。我也很难通过括号和逗号解析,并且不确定如何用文本文件中正确的数字初始化变量。

解析不应该那么困难,尤其是您可以使用 std::stringstream将所有元素与输入分开时。实际上,您想先删除所有衍生作品,然后将元素放在容器中。

#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <cctype>
int main()
{
    std::ifstream read("file.txt");
    std::vector<std::vector<std::pair<int, int>>> graph;
    // read until you reach the end of the file
    for (std::string line; std::getline(read, line); ) {
        // removing punctuation like paranthesis, commas, etc.
        std::replace_if(std::begin(line), std::end(line), [] (char x) { return std::ispunct(x); }, ' ');
        // inserting the line into a stream that helps us parse the content
        std::stringstream ss(line);
        // read the node number
        int source, destination, weight;
        ss >> source;
        // create a new vector for the new node, so you can place all it's destinations / weights in it
        graph.insert(std::next(std::begin(graph), source), {{}});
        // read the dests / weights until you reach the end of the current line
        while (ss >> destination >> weight)
            graph[source].emplace_back(destination, weight);
    }
    read.close();
    std::ofstream write("output.txt");
    for (const auto node : graph) {
        for (const auto [dest, weight] : node)
            write << "(" << dest << ", " << weight << ") ";
        write << 'n';
    }
}

请注意,您需要C 17来编译代码。如果您使用较旧的C 标准,则必须使用基本循环而不是ranged-for loops并省略auto。我也使用了一个对向量,但是如果您使用struct/class进行节点,更好的是使代码更加可维护。

这也有效。

#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main() {
    int vertices[1000][3], qv = 0;  //use number more than 1000 if it is required
    while (cin) {
        int n;
        char c;
        string s;
        getline(cin, s);
        istringstream is(s);
        is >> n;
        is >> c;
        while (c == '(') {
            vertices[qv][0] = n;
            is >> vertices[qv][1];
            is >> c;   //,
            is >> vertices[qv++][2];
            is >> c;   //)
            is >> c;   //(
        }
    }
    for (int i = 0; i < qv; i++) //unified view
        cout << vertices[i][0] << ' ' << vertices[i][1] << ' ' << vertices[i][2] << endl;
    for (int i = 0; i < qv; i++) {  //initial view
        cout << vertices[i][0];
        cout << " (" << vertices[i][1] << "," << vertices[i][2] << ")";
        while (i + 1 < qv && vertices[i][0] == vertices[i + 1][0]) {
            i++;
            cout << " (" << vertices[i][1] << "," << vertices[i][2] << ")";
    }
    cout << endl;
}

}

我会使用类似的东西:

#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <algorithm>
struct coordinate
{
    int vertex;
    int weight;
};
struct vertex_set
{
    int vertex;
    std::vector<coordinate> coordinates;
};
std::istream& operator>>(std::istream &in, coordinate &out)
{
    char ch1, ch2, ch3;
    if (in >> ch1 >> out.to_vertex >> ch2 >> out.weight >> ch3)
    {
        if ((ch1 != '(') || (ch2 != ',') || (ch3 != ')'))
            in.setstate(std::ios_base::failbit);
    }
    return in;
}
std::istream& operator>>(std::istream &in, std::vector<coordinate> &out)
{
    out.clear();
    coordinate coord;
    while (in >> coord)
        out.push_back(coord);
    return in;
}
std::istream& operator>>(std::istream &in, vertex_set &out)
{
    return in >> out.vertex >> out.coordinates;
}
std::ifstream f("file.txt");
std::string line;
while (std::getline(f, line))
{
    vertex_set vs;
    if (std::istringstream(line) >> vs)
    {
        // use vs.vertex and vs.coordinates as needed... 
    }
}