如何获取递归函数中的下一行

How to get the next line in a recursive function

提问人:Tom Burrows 提问时间:5/25/2022 最后编辑:Ken WhiteTom Burrows 更新时间:5/25/2022 访问量:290

问:

我正在尝试创建一个递归函数,该函数将遍历一个文件,并且对于每一行,将创建一个对象的实例,为该对象提供名称、属性列表和以前的名称(所有名称都是唯一的,因此我无需担心相似性)。

代码如下:

    void getTags(string prevname){
        fstream file;
        file.open("source.txt");

        string name;
        // Getting current line, and splitting it.
        string str;


        getline(file, str);
        cout << str << endl;

        vector<string> currentLine = splitString(str, ' ');

        // Getting tag name
        if(!isClosing(str)){

            for (int i = 1; i < (int)currentLine[0].size(); i++){
                name += currentLine[0][i];
            }

            Tag tag = Tag(name, prevname);

            if(hasAttr(str)){
                vector<pair<string, string>> temp = getAttr(currentLine);
                for(int i = 0; i < (int)temp.size(); i++){
                    tag.addAttribute(temp[i]);
                }
            }
            
            tags.push_back(tag);
            getTags(name);
        } else {
            getTags(prevname);
        } 
    }
};

出于某种原因,我的没有得到下一行,而只是递归,直到我遇到分段错误。我也试过了.但这也没有用。getline(file, str)file >> str

我尝试打印该行以检查它是否确实转到下一行,但它将始终停留在第一行。

我不确定我到底哪里出了问题,任何帮助将不胜感激。

文件中的每一行都如下所示:name value="value" value2 = "value2"

C++ 递归 fstream IOSTREAM

评论

1赞 user4581301 5/25/2022
始终在每个 IO 事务后测试流状态。在过去,一个常见的错误是,在读取失败后,它不会修改它所填充的字符串,你最终会得到一个看起来永远循环在同一行上的程序,有点像你报告的内容。换言之,将getlinegetline(file, str);if (getline(file, str)) { do stuff with str } else { log error and clean up the stream, if you can }
0赞 Eugene 5/25/2022
您的函数缺少终止条件 - 它永远不会返回,最终导致堆栈溢出。您应该使用 return from 作为终止条件。getline()

答:

2赞 fireshadow52 5/25/2022 #1

你的第一个问题是你的递归没有基本情况(即终止条件),所以在你填满调用堆栈之前一直被调用,这时你会得到分段冲突。解决此问题的方法是创建一个终止条件,在这种情况下,当您用尽文件中的所有输入时。getTags

第二个问题是,每次递归调用都会再次打开文件,并将其分配给 的新实例。这意味着,无论到目前为止进行了多少次递归调用,您的调用始终将读取第一行(请记住,在一个递归调用中定义的局部变量不会结转到后续调用中)。解决此问题的一种方法是在开始递归之前打开文件,并将 as 参数传递给 。这样,您就不会不必要地多次打开文件,并且您实际上能够正确读取文件。fstream filegetlinefstreamgetTags

鉴于以上两点,的一般结构可能如下所示:getTags

void getTags(fstream &file, string prevName) {
    string line;
    
    result = getline(file, line);

    if (!result) {
        // This is your base case. If result == false, the call to getline failed (due to EOF or some other reason)
        return;
    }

    // Main function logic here...

    vector<string> currentLine = splitString(line, ' ');

    if (!isClosing(line) ) {
        // ...

}