C++ завершается вызовом после создания экземпляра 'std::out_of_range', вектора строки

Я получаю эту ошибку при запуске:

прекращение вызова после выброса экземпляра 'std::out_of_range' what(): 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 ответа

Две основные проблемы здесь.

Ваш цикл будет продолжаться вечно (или до тех пор, пока вы не убьете свои ОЗУ из-за недопустимого доступа), потому что вы проверяете только, что вектор не пуст, а не проверяете, что 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 операции, которые имеют неправильные аргументы и, таким образом, вызывают исключение.

Давайте попробуем исправить фрагмент вашей программы:

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

И так далее...

Другие вопросы по тегам