抛出'std :: out_of_range'的实例后调用terminate():basic_string :: substr

时间:2014-03-02 16:23:54

标签: c++ substr

我收到此错误:“抛出'std :: out_of_range'实例后调用终止   来自此代码的what():basic_string :: substr“

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cstdlib>

using namespace std;

vector <string> n_cartelle;

ifstream in("n_cartelle.txt");
string linea;

while(getline(in,linea))
n_cartelle.push_back(linea);


for(int i=0; i < 4; ++i){


if(n_cartelle[i].substr(n_cartelle[i].size()-3) == "txt")
cout <<"si"<<endl;
else
cout<<"no"<<endl;

}

如果我尝试这个:

if(n_cartelle[7].substr(n_cartelle[7].size()-3) == "txt")
cout <<"si "<<n_cartelle[7]<<endl;
else
cout<<"no"<<endl;

我没有收到错误。

1 个答案:

答案 0 :(得分:13)

您遇到的情况可能是异常从main()掉落,它会终止程序并提供与您发布的错误消息类似的操作系统错误消息。

作为第一项措施,您可以在main()中捕获异常。这样可以防止程序崩溃。

#include <exception>
#include <iostream>

int main()
{
    try
    {
        // do stuff
    }
    catch (std::exception const &exc)
    {
        std::cerr << "Exception caught " << exc.what() << "\n";
    }
    catch (...)
    {
        std::cerr << "Unknown exception caught\n";
    }
}

现在你已经有了这个机制,你可以实际找到错误。

查看您的代码,可能n_cartelle少于4个元素,可能由n_cartelle.txt引起,只包含3行。这意味着n_cartelle[0]n_cartelle[1]n_cartelle[2]会很好,但尝试访问n_cartelle[3]以及其他任何内容都将是未定义的行为,这基本上意味着任何事情可能会发生。因此,首先要确保n_cartelle实际上有4个元素,并且您的程序已经定义了行为。

接下来可能出错的事情(更可能是说实话)是substr()电话。当您尝试使用“不可能”参数调用substr()时,例如从包含仅5个字符的字符串的字符10开始获取子字符串,则行为已定义错误 - a {抛出异常{1}}。当您意外地尝试将负数作为std::out_of_range的第一个参数传递时,也会发生(间接地,几乎每次)。由于substr()的内部工作原理,负数将转换为一个巨大的正数,肯定比字符串长得多,并导致相同的std::string异常。

所以,如果你的一条线的长度少于3个字符,std::out_of_range是负数,我刚才解释的就是。