2014-04-10 160 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); 
} 

等等......

相關問題