【问题标题】:Confusing "std::out_of_range" Error令人困惑的“std::out_of_range”错误
【发布时间】:2011-12-18 02:02:00
【问题描述】:

过去 2 小时我一直在调试此错误,并且知道自己如果在睡觉前不寻求帮助,我将无法入睡。我正在为我的游戏编写一个模型加载器,而现在我正在使用一种非常脆弱的方法来拆分字符串。但是,它适用于几乎相同的线路,然后随机不运行。我正在使用 string.substr(),我相信错误意味着它试图从字符串中不存在的位置开始。调用堆栈说它发生在这一行:

v1 = v1.substr(s.find(",")+1);

并通过使用打印消息的断点,它说

顶点 1 使用“1,1”,整个字符串为“173,1,1 175,1,1 174,1,1"

其中 Vertex 1 是 v1 的值,string 是 s 的值。

这是整个函数:

FaceData data;
s = s.substr(5); //remove "FACE "
string v1, v2, v3;

//vertex 1
v1 = s.substr(0, s.find(" "));

data.vertexIndexes[0] = atoi(v1.substr(0, s.find(",")).c_str());
v1 = v1.substr(s.find(",")+1);
data.textureIndexes[0] = atoi(v1.substr(0, s.find(",")).c_str());
v1 = v1.substr(s.find(",")+1);
data.normalIndexes[0] = atoi(v1.c_str());

//vertex 2
s = s.substr(s.find(" ")+1);
v2 = s.substr(0, s.find(" "));

data.vertexIndexes[1] = atoi(v2.substr(0, s.find(",")).c_str());
v2 = v2.substr(s.find(",")+1);
data.textureIndexes[1] = atoi(v2.substr(0, s.find(",")).c_str());
v2 = v2.substr(s.find(",")+1);
data.normalIndexes[1] = atoi(v2.c_str());

//vertex 3
s = s.substr(s.find(" ")+1);
v3 = s;

data.vertexIndexes[2] = atoi(v3.substr(0, s.find(",")).c_str());
v3 = v3.substr(s.find(",")+1);
data.textureIndexes[2] = atoi(v3.substr(0, s.find(",")).c_str());
v3 = v3.substr(s.find(",")+1);
data.normalIndexes[2] = atoi(v3.c_str());

return data;

传递给函数的 std::string 's' 总是如下所示: "脸 X,X,X X,X,X,X,X,X" 其中 x 是一个数字。

这是我能找到的分割字符串的唯一方法...

现在,我不明白为什么这里会出现此错误...似乎它几乎只是随机发生的。我不明白为什么它不能与

173,1,1 175,1,1 174,1,1

但它适用于

175,2,2 176,2,2 175,2,2

【问题讨论】:

  • 您可能需要粘贴更多源代码,然后才能有人发现问题。
  • 只是在这里猜测,但如果你有一个像hi, 这样的字符串,+1 可能会要求substr 从一个无效的位置开始。
  • 呃,对不起,我什至不知道我最后写的垃圾是什么意思……但我补充了更多……

标签: c++ stdstring


【解决方案1】:

我不确定我是否正确解释了您的问题,但鉴于您提供的信息,这似乎是您正在做的事情:

#include <string>
#include <iostream>

int main() {
    std::string v1 = "1,1";
    std::string s = "173,1,1 175,1,1 174,1,1";

    try {
        v1 = v1.substr(s.find(",")+1);
    }
    catch (const std::out_of_range& e) {
        std::cout << "out_of_range: " << e.what() << std::endl;
        return 1;
    }
    return 0;
}

在这种情况下,s.find(",") 将返回 3s 中的第一个 , 位于位置 3),但是由于 v1 只有三个字符,因此唯一有效的索引在 [0,2] 之间。传入3 或使用+1 4 将超出v1 的范围。

【讨论】:

  • 根据您最新的代码示例,我会调查为什么您在 s 中而不是在 v1 中找到“,”。由于您使用的是 v1 的子字符串,因此您对起始字符的搜索似乎也应该针对该变量。
猜你喜欢
  • 2018-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 2012-09-12
  • 1970-01-01
  • 1970-01-01
  • 2020-04-30
相关资源
最近更新 更多