使用get_line读取文件时,提取带括号的字符串中的数字 一个问题让我困惑了C++初学者一段时间。

使用get_line读取文件时,提取带括号的字符串中的数字 一个问题让我困惑了C++初学者一段时间。,c++,C++,我将大量数字数据以以下方式存储在文件中: (123 34412 24) (13 34324 2214) (143 21342 24123) (1323 341422 23244) (14123 32342 2413) .... 我想阅读这些数据,希望提取第一列来做一些科学计算,第二列和第三列也希望同时提取 我不知道它是什么数据结构,并且检查了一些参考文献,发现没有答案,似乎不是列表、向量等 我希望使用如下代码来完成这项工作 #include <fstream> #include &

我将大量数字数据以以下方式存储在文件中:

(123 34412 24)
(13 34324 2214)
(143 21342 24123)
(1323 341422 23244)
(14123 32342 2413)
....
我想阅读这些数据,希望提取第一列来做一些科学计算,第二列和第三列也希望同时提取

我不知道它是什么数据结构,并且检查了一些参考文献,发现没有答案,似乎不是列表、向量等

我希望使用如下代码来完成这项工作

#include <fstream>
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
    ifstream file("input.dat");
    string lineBuf;
    int *col1[], *col2[], *col3[];

    if (file.is_open())
    {
        while(getline(file, lineBuf)
            {
                //  how to convert lineBuf to separated numbers
                //  and assign to col1 col2 col3 separately here?
            }
    }
    return 0;
}
虽然我无法获得正确的bc输出,但您不需要在这里使用getline或任何字符串操作。我们可以利用这样一个事实:操作符>>只读取调用它的类型,而忽略读取每个数字的空白

char eater; // this is to consume the ( and ) on each line
int number1, number2, number3;

std::ifstream fin("some_file_name.txt");

while (fin >> eater >> number1 >> number2 >> number3 >> eater) // will stop when it can't read anymore
{
    // do something with the numbers
} // loop back and read the next line

在上面的代码中,第一个>>食客将读取单个字符。这将吃掉开始时的数字,允许我们使用运算符>>获取3个数字。最后一个>>进食者在最后消耗了,让我们准备好阅读下一行。

尝试使用此片段,并根据需要对其进行修改:

std::list<float> readNumberListFromLine(const std::string &line) {
    std::stringstream stream(line);
    std::list<float> nums;
    char chr = 0;
    // Wait for a "(" token.
    while(1 == 1) {
        stream >> chr;
        // If failed to read a character, it means eof
        if (stream.fail()) break;
        if (chr == '(') break;
    }

    // Clear the stream state, to clear the "fail" bit, to allow reading more while we
    // check on this state
    stream.clear();
    while(1 == 1) {
        float num;
        stream >> num;
        // If failed to read a number, stream of numbers have stopped, don't read numbers more.
        if (stream.fail()) { break; }
        nums.push_front(num);
    }
    stream.clear();
    // This part shouldn't be like that, DRY principle says "Don't repeat yourself"
    // This should be in a function because it is a repeat of the first loop
    // But this would have templates and things that aren't simple
    while(1 == 1) {
        stream >> chr;
        if (stream.fail()) return std::list<float>();
        if (chr == ')') break;
    }
    return nums;
}

void printList(const std::list<float> &list) {
    // We don't want pop to affect the original
    std::list<float> copy = list;
    while (!copy.empty()) {
        // We pushed on the front,  so when we pop, pop from back, push/pop is a LIFO mechanism
        // Last-in-first-out,  we don't want this behaviour.
        std::cout << copy.back() << " ";
        copy.pop_back();
    }
}

void printListOfListsOfFloats(const std::list<std::list<float>> &data) {
    std::list<std::list<float>> copy = data;

    while(!copy.empty()) {
        printList(copy.back());
        copy.pop_back();
        std::cout << "\n";
    }
}

int main() {
    std::ifstream stream("/Users/fadi/code.dat");
    std::list<std::list<float>> data;
    std::string line;
    while (1 == 1) {
        std::getline(stream, line);
        if (stream.fail()) break;
        std::list<float> tmp = readNumberListFromLine(line);
        if (!tmp.empty()) { data.push_front(tmp); }
    }

    printListOfListsOfFloats(data);
}

标准库中没有函数std::get_line。每个数据集之间是否都有一个空行?另外,每行的列数是否相同?很抱歉,getlineno行与行之间没有空格,我必须添加\n以在此处打断它们。每行有3个可能的重复数字,我们也可以使用数字数组来概括此解决方案,而不是硬编码反序列化数字1、数字2和数字3。尝试读取整数并将其放入向量或列表中,直到流中没有整数为止,然后读取EaterRight是否值得拥有两个eater变量,并检查它们是否等于预期的和。多检查一点错误不会有什么坏处。@user9335240我已经更新了问题。不幸的是,在同一个文件中还有一些其他字符串,这段代码似乎不适合处理这些字符串together@Eric您是否考虑过使用正则表达式筛选那些不符合该模式的记录?再一次请发布您的文件输入和代码。@Eric我已将编辑回滚到您的Q,因为它使此答案无效。如果你的文件中有更多的内容,你应该问一个新的问题,如果你不关心它,你应该如何读入它,或者忽略它,这样你就可以得到你需要阅读的数字行。
char eater; // this is to consume the ( and ) on each line
int number1, number2, number3;

std::ifstream fin("some_file_name.txt");

while (fin >> eater >> number1 >> number2 >> number3 >> eater) // will stop when it can't read anymore
{
    // do something with the numbers
} // loop back and read the next line
std::list<float> readNumberListFromLine(const std::string &line) {
    std::stringstream stream(line);
    std::list<float> nums;
    char chr = 0;
    // Wait for a "(" token.
    while(1 == 1) {
        stream >> chr;
        // If failed to read a character, it means eof
        if (stream.fail()) break;
        if (chr == '(') break;
    }

    // Clear the stream state, to clear the "fail" bit, to allow reading more while we
    // check on this state
    stream.clear();
    while(1 == 1) {
        float num;
        stream >> num;
        // If failed to read a number, stream of numbers have stopped, don't read numbers more.
        if (stream.fail()) { break; }
        nums.push_front(num);
    }
    stream.clear();
    // This part shouldn't be like that, DRY principle says "Don't repeat yourself"
    // This should be in a function because it is a repeat of the first loop
    // But this would have templates and things that aren't simple
    while(1 == 1) {
        stream >> chr;
        if (stream.fail()) return std::list<float>();
        if (chr == ')') break;
    }
    return nums;
}

void printList(const std::list<float> &list) {
    // We don't want pop to affect the original
    std::list<float> copy = list;
    while (!copy.empty()) {
        // We pushed on the front,  so when we pop, pop from back, push/pop is a LIFO mechanism
        // Last-in-first-out,  we don't want this behaviour.
        std::cout << copy.back() << " ";
        copy.pop_back();
    }
}

void printListOfListsOfFloats(const std::list<std::list<float>> &data) {
    std::list<std::list<float>> copy = data;

    while(!copy.empty()) {
        printList(copy.back());
        copy.pop_back();
        std::cout << "\n";
    }
}

int main() {
    std::ifstream stream("/Users/fadi/code.dat");
    std::list<std::list<float>> data;
    std::string line;
    while (1 == 1) {
        std::getline(stream, line);
        if (stream.fail()) break;
        std::list<float> tmp = readNumberListFromLine(line);
        if (!tmp.empty()) { data.push_front(tmp); }
    }

    printListOfListsOfFloats(data);
}