2014-04-10 70 views
-10

我收到此错误的载体:C++终止叫做抛出的“的std :: out_of_range”的实例后,串

终止抛出的一个实例后调用“的std :: out_of_range”什么( ):basic_string :: substr

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

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++; 
    } 
+2

嗯,你在外面访问矢量的范围。 – juanchopanza

+0

错误发生时'content [i]'的值是多少? – Barmar

+1

@juanchopanza错误在'substr'中,而不是矢量访问器。 – Barmar

回答

3

这里有两个主要问题。

您的循环将永远持续(或直到您从无效访问中谋杀您的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操作,这有错误的论点,并从而导致异常。

+0

没有int i = 1因为在第一行我有女巫的数据我不需要复制子字符串。 – user3084640

+0

如果这个错误对OP是不言自明的,他不会问这个问题。 – Barmar

+0

@ user3084640:好吧,你还没有做任何边界检查。 –

2

让我们来尝试修复你的程序片断:

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); 
} 

等等......

相关问题