C++ std::string::at 抛出 std::out_of_range [关闭]

Posted

技术标签:

【中文标题】C++ std::string::at 抛出 std::out_of_range [关闭]【英文标题】:C++ std::string::at throwing std::out_of_range [closed] 【发布时间】:2014-06-21 20:06:54 【问题描述】:
void Display::displayText(const char* text) 
    using std::string;
    using std::vector;
    string line = string(text);
    vector<string> temp(1);
    if (Display::startLine < 0) Display::startLine = 0;
    bool cont = true;
    int lastRegex = 0;
    int regex = 1;
    string tmp = string(" ");
    for (int i=0; i<line.length(); i++) 
        if(line.at(i)=='\n') 
            tmp = line.substr(lastRegex, i-lastRegex);
            tmp.erase(tmp.find("\n"), tmp.find("\n"));
            lastRegex = i+1;
            regex++;
            temp.resize(regex);
            temp[regex-1] = tmp;
        
        if (i - lastRegex == COLS-3) 
            bool b = true;
            int j = i;
            while (b) 
                if (line.at(i) == ' ') 
                    b = false;
                    tmp = line.substr(lastRegex, j-lastRegex);
                    lastRegex = j+1;
                    regex++;
                    temp.resize(regex);
                    temp[regex-1] = tmp;
                
                j--;
            
        
    
    regex++;
    temp.resize(regex);
    temp[regex-1] = line.substr(lastRegex, string::npos);

    if (Display::startLine+1 > temp.size()) Display::startLine = temp.size()-1;
    for (int i=0; i<temp[startLine].length(); i++) Window::draw(i+1, 1, temp[Display::startLine].at(i));
        if (Display::startLine+1 <= temp.size()-1)
            for (int i=0; i<temp[Display::startLine+1].length(); i++) Window::draw(i+1, 2,                 temp[Display::startLine].at(i));
        if (Display::startLine > 0) Window::draw(COLS-2, 1, '^');
        if (Display::startLine + 1 < temp.size()-1) Window::draw(COLS-2, 2, 'v');
    

此代码编译正确。但是,当我运行它时,我收到 std::basic_string::atstd::out_of_range 错误。

我尝试添加检查行是否为空,并将 for 循环更改为 .length()-1,但两者都产生相同的结果。

这个函数应该接收文本,并将其显示在窗口的顶部两行(因此是 COLS 变量和Window::draw),如果文本扩展过去,则在行尾添加箭头两条线。我当前输入的引发错误的文本是“Hello World!”。

如果我使用Window::draw 手动显示相同的文本,则绘图功能没有问题。 (此方法专门用于自动将文本环绕在屏幕周围并在两行处加盖)

【问题讨论】:

我们不能替代您的调试器:/ std::out_of_range - 这意味着您使用 .at() 访问不存在的数组元素 与其使用for (int i=0; i&lt;line.length(); i++),不如使用for(auto ch; line) @RSahu 我需要使用 i 来获取正确的子字符串 这种情况下,可以在循环前定义并初始化i,使用for ( auto it = line.begin(); it != line.end(); ++it, ++i ) 【参考方案1】:

字符串是从 0 开始索引的字符数组。如果你想访问第一个字符,它在位置 0,如果你想访问最后一个字符,它在位置长度 -1。

例如,字符串 test = "hello";

test.at(0) 会给我'h',test.at(4) 会给我'0',test.at(5) = test.at(test.length()) = out of range错误

将你的 for 循环更改为

  for (int i=0; i<line.length() - 1; i++) 

【讨论】:

在这种情况下,最后一个 i 将是 line.length()-2 -1 和 -2 都不起作用。但是, 至于为什么代码仍然失败,我没有任何更新,但是关于 for 循环,考虑一个带有约束 i 我测试了代码:'string str("Hello"); for (int i=0; i 哇,你说的完全正确,我不知道我在想什么!我会回去看看我是否在您的代码中找到其他任何内容。

以上是关于C++ std::string::at 抛出 std::out_of_range [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如果我不告诉 C++ 中要抛出啥类型的对象,会抛出啥 throw 语句?

C++之路进阶——ST表(降雨量)

如何在 swig 接口文件中集成可以抛出 MyException 的 C++ 函数

C++:抛出异常会调用复制构造函数?

抛出异常:写访问冲突 C++

(c++) 在抛出一个实例后调用终止