繁体   English   中英

将文件读取到矢量的矢量中,超出范围错误

[英]Read file to vector of vectors, out of range error

我正在开发一个解决项目难题的程序。 要求是迷宫文本文件的长度能够以任何方式变化,并且必须将其读取为字符向量的向量。

到目前为止,我已经创建了一个程序,该程序至少应该在我的脑海中起作用,有一个while循环为文件中的每一行添加了一行到矢量。 我正在文件的当前行上使用.at()运算符使用带有推回的简单for循环。 在底部,我有一个简单的for循环以显示第一行。 问题是向量始终超出范围错误。

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

using namespace std;



int main(){
    ifstream file;
    string fileName;
    string Line;
    vector<vector<char>> Maze;
    cout << "Enter the maze file name and extension: " << endl;
    cin >> fileName;
    file.open(fileName);

    while (getline(file, Line)) {
        int rowNumber = 0;
        vector<char> row;
        Maze.push_back(row);
        for (int i = 0; i < Line.size(); i++) {
            Maze[rowNumber].push_back(Line.at(i));
        }
        rowNumber++;
    }
    for (int i = 0; i < 5; i++) {
        cout << Maze[0][i];
    }

    system("pause");
    return 0;
}

我使用的测试文件有5行,每行5个字符,没有空格。 我希望程序会打印出文件的第一行,相反,我会收到“调试声明失败”错误,并指出矢量下标超出范围。 任何帮助表示赞赏

您的代码有几个注释。

如图所示,它可以正常工作。 它不会产生运行时错误,但也不会产生预期的结果。

问题是您总是在while循环开始时始终将变量rowNumber设置为0。 rowNumber++; 最后一阵子将无效。 因此,您一直在向Maze[0]添加字符。

那是你的语义错误。

是,当您尝试访问Maze[1][i]时,出现了我们的运行时错误。

然后,使用C ++算法可以大大缩短您的代码。 看到:


#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>


std::istringstream testDataFile(
R"#(00000
11111
22222
33333
44444
)#");



// This is a proxy to read a complete line with the extractor operator
struct CompleteLineAsVectorOfChar {
    // Overloaded Extractor Operator
    friend std::istream& operator>>(std::istream& is, CompleteLineAsVectorOfChar& cl) {
        std::string s{}; cl.completeLine.clear();  std::getline(is, s); 
        std::copy(s.begin(), s.end(), std::back_inserter(cl.completeLine));
        return is; }

    operator std::vector<char>() const { return completeLine; }  // Type cast operator for expected value
    std::vector<char> completeLine{};
};


int main()
{
    // Read complete source file into maze, by simply defining the variable and using the range constructor
    std::vector<std::vector<char>> maze { std::istream_iterator<CompleteLineAsVectorOfChar>(testDataFile), std::istream_iterator<CompleteLineAsVectorOfChar>() };

    // Debug output:  Copy all data to std::cout
    std::for_each(maze.begin(), maze.end(), [](const std::vector<char> & l) {std::copy(l.begin(), l.end(), std::ostream_iterator<char>(std::cout, " ")); std::cout << '\n'; });

    return 0;
}

但这还没有结束。 std::vector<char>与字符串相比没有优势。 您几乎可以使用与std::vector<char>相同的功能。 那是设计上的改进。 该代码将看起来像这样:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>

std::istringstream testDataFile(
R"#(00000
11111
22222
33333
44444
)#");

int main()
{
    // Read complete source file into maze, by simply defining the variable and using the range constructor
    std::vector<std::string> maze{ std::istream_iterator<std::string>(testDataFile), std::istream_iterator<std::string>() };

    // Debug output:  Copy all data to std::cout
    std::copy(maze.begin(), maze.end(), std::ostream_iterator<std::string>(std::cout, "\n"));

    return 0;
}

这是迄今为止更为简单的解决方案。 它也将满足您的需求。

请注意:因为我在SO上没有文件,所以我使用istringstream读取数据。 但这与使用其他任何流(例如ifstream)的原因相同。

希望这可以帮助 。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM