【问题标题】:C++ terminate called after throwing an instance of 'std::out_of_range', vector of string在抛出一个'std :: out_of_range'实例后调用C ++终止,字符串向量
【发布时间】:2014-05-24 19:13:38
【问题描述】:

运行时出现此错误:

在抛出 'std::out_of_range' 的实例后调用终止 what(): basic_string::substr

问题出在这部分代码中,但我是全新的,我不明白应该如何解决这个问题。 content 是我的字符串向量。

    int i=1;
    std::string v1, v2, weight;
    while(!content.empty())
    {
        v1 = content[i].substr(2,1);
        v2 = content[i].substr(5,1);
        weight = content[i].substr(8,1);
        i++;
    }

【问题讨论】:

  • 嗯,您访问的向量超出范围。
  • @juanchopanza 错误在substr,而不是向量访问器。
  • @Barmar 你怎么能确定substr 有问题?你见过存储在向量中的字符串吗?
  • @Barmar:不是在你对它执行[] 时,不。
  • @user3084640:嗯,那也错了。它实际上有很多更多错误。当向量在循环期间从不减小大小时,为什么要尝试根据向量是否为空来控制循环的生命周期? C++ 新手与否只是缺乏常识。查看 C++ 书中有关如何迭代容器的部分。

标签: c++ c++11 outofrangeexception


【解决方案1】:

这里有两个主要问题。

您的循环将永远持续下去(或者直到您从无效访问中删除您的 RAM 棒),因为您只检查向量是否为空,而不是检查 i 是否已达到其总大小。

for (auto& x : content) {
    const std::string v1     = x.substr(2,1);
    const std::string v2     = x.substr(5,1);
    const std::string weight = x.substr(8,1);

    // Presumably actually do something with these now
}

然后你需要修复你的 substr 操作,它有错误的参数,从而导致异常。

【讨论】:

  • no int i=1 因为在第一行我有来自女巫的数据,我不需要复制子字符串。
  • 如果错误对 OP 来说是不言自明的,他就不会问这个问题。
  • @user3084640:好吧,你还没有做任何边界检查。
  • @Barmar:这在英语范围内是不言自明的。如果有人想掩盖显而易见的事情,那我就无能为力了。
  • 不会有人想公羊棒吗??
【解决方案2】:

让我们尝试修复您的程序 sn-p:

int i=1;
std::string v1, v2, weight;
while( i < content.size() && content[i].size() >= 8 )
{
    v1 = content[i].substr(2,1);
    v2 = content[i].substr(5,1);
    weight = content[i].substr(8,1);
    i++;
}

这是最小的修复。我会更喜欢:

std::string v1, v2, weight;
content.erase(content.begin());
for( const auto& x: content )
{
    if( x.size() < 8 )
         continue; // or break, whatever is best

    v1 = x.substr(2,1);
    v2 = x.substr(5,1);
    weight = x.substr(8,1);
}

您还可以改变对待较短物品的方式:

inline int guarded_substr(const std::string& s, std::size_t begin, size_t size) {
    return s.size() >= begin+size ? s.substr(begin, size) : std::string();
}

std::string v1, v2, weight;
content.erase(content.begin());
for( const auto& x: content )
{
    v1 = guarded_substr(x,2,1);
    v2 = guarded_substr(x,5,1);
    weight = guarded_substr(x,8,1);
}

等等……

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-02
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多