Почему «завершение вызывается после создания экземпляра «std::out_of_range» что(): базовая строка::в: __n (что равно 0) >= это->>размер() (который равен 0)»?

#c

Вопрос:

Итак, я продолжаю получать

завершение вызывается после создания экземпляра ‘std::out_of_range’
что(): базовая строка::в: __n (что равно 0) >= это->>размер() (который равен 0)

сообщение, когда я пытаюсь запустить свой код. Что я пытаюсь сделать, так это сделать так, чтобы он выводил двойник, сохраненный между первой фигурной скобкой и запятой в переменной nm_1. (*извините, если мой код немного запутан, уже поздно)

 int main() {
    std::string funct;
    
    std::cout << "-->";
    std::cin >> funct;
    
    if (funct.find("math") != std::string::npos) {
        int bracket_pos_1 = funct.find("{");
        int bracket_pos_2 = funct.find("}");
        int temp = 0;
        // int temp_2 = 0;
        std::string nm_1;
        std::string nm_2;
        auto split_string = funct.substr(bracket_pos_1   1, bracket_pos_2 - bracket_pos_1  - 1);
        // string ss = split_string;
        for (int i = 0; i < 2; i) {
            std::string nm_1;
            string ss = split_string;
            if (ss.at(temp) == '0' || ss.at(temp) == '1' || 
                ss.at(temp) == '2' || ss.at(temp) == '3' || 
                ss.at(temp) == '4' || ss.at(temp) == '5' || 
                ss.at(temp) == '6' || ss.at(temp) == '7' ||         
                ss.at(temp) == '8' || ss.at(temp) == '9') {
                nm_1.at(temp) = ss.at(temp);
            } 
            else if (ss.at(temp) == '.') {
                nm_1.at(temp) = ss.at(temp);
                i  ;
            }
            else if (ss.at(temp) == ',') {
               i = 2;
            }

            temp  ; 
        }
            
        nm_1.at(temp - 1) = '0';
        // std::cout << split_string;
        cout << endl << endl << nm_1;
    }
}
 

Комментарии:

1. Добро пожаловать в Stack Overflow. Когда вы читаете сообщение terminate called after throwing an instance of 'std::out_of_range' what(): basic_string::at: __n (which is 0) >= this->size() (which is 0) , что, по-вашему, оно означает ? Что конкретно вы в этом не понимаете?

2. Вы позвонили .at с индексом, превышающим длину строки. Я предлагаю вам загрузить отладчик и выяснить, какие из многих, многих .at вызовов строк завершаются неудачно.

3. Может быть, вам стоит распечатать ss и посмотреть, что в нем.

Ответ №1:

Первая проблема заключается в следующем:

 std::string nm_1;
nm_1.at(temp) = ...
 

Вы не можете перезаписать символы, которых нет в строке. Вам лучше добавить к строке. Проще всего было бы использовать = оператор:

 nm_1  = ...
 

Вторая проблема связана с этим:

 std::string nm_1;
for (...) {
    std::string nm_1;
    nm_1  = ...
 

Любое изменение, которое вы сделаете nm_1 , произойдет с этой переменной внутри цикла. Проблема в том, что эта переменная уничтожается в конце одной итерации и создается заново в начале следующей итерации, поэтому все ваши изменения, выполненные внутри цикла, теряются. Просто удалите это определение переменной, чтобы исправить это:

 std::string nm_1;
for (...) {
    nm_1  = ...
 

Ответ №2:

Функция .at() -член выдаст исключение, если вы попытаетесь получить доступ к элементам, которые находятся за пределами. Ваш std::string nm_1 по умолчанию пуст (не содержит элементов). Если вы позвоните nm_1.at(x) и предоставите какой-либо индекс вообще, он всегда будет выбрасываться, потому что в нем нет элементов. Это применимо, даже если вы пытаетесь поместить элементы в строку.

Если вы хотите добавить символы в конец строки, вы можете использовать nm_1.push_back() функцию-член. В качестве альтернативы, если вы знаете желаемую длину вывода, вы можете использовать .resize() ее заранее, и тогда вы сможете использовать .at() ее соответствующим образом ( .resize() метод позволяет вам выбрать, каким символом заполнять строку, по умолчанию это нулевой символ).

Кроме того, вы объявляете std::string nm_1 дважды, один раз вне цикла и один раз внутри цикла. Объявление внутри цикла «затеняет» объявление вне цикла. В принципе, это означает, что каждый раз, когда вы ссылаетесь на nm_1 внутри цикла, тот, который объявлен вне цикла, останется неизменным.