Home > Software engineering >  Why "terminate called after throwing an instance of 'std::out_of_range' what(): basic
Why "terminate called after throwing an instance of 'std::out_of_range' what(): basic

Time:09-25

So, I keep receiving the terminate called after throwing an instance of 'std::out_of_range' what(): basic_string::at: __n (which is 0) >= this->size() (which is 0) message when I try to run my code. What I'm trying to do is to make it so that it outputs the double stored between the first curly brace and the comma in the nm_1 variable. (*sorry if my code is a bit messy, it's late)

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

}

CodePudding user response:

The first problem is this:

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

You can't overwrite characters that don't exist in the string. You should rather append to the string. The easiest would be using = operator:

nm_1  = ...

The second problem is with this:

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

Any modification you do to nm_1 will happen to that variable inside the loop. The problem is that this variable is destroyed at the end of one iteration and created anew at the beginning of the next iteration, so all your modification done inside the loop are lost. Just remove that variable definition to fix it:

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

CodePudding user response:

The .at() member function will throw an exception if you try and access elements that are out-of-bounds. Your std::string nm_1 is empty by default (contains no elements). If you call nm_1.at(x) and supply any index at all, it will always throw, because there are no elements. This applies even if you are attempting to put elements into the string.

If you want to add characters to the end of a string, you can use nm_1.push_back() member function. Alternatively, if you know the desired length of the output, you can use .resize() in advance, and then you will be able to use .at() accordingly (the .resize() method lets you choose what character to fill the string with, by default it is the null character).

Also, you declare std::string nm_1 twice, once outside the loop, and once inside the loop. The declaration inside the loop "shadows" the one outside the loop. Basically, this means any time you refer to nm_1 inside the loop, the one declared outside the loop will remain unaffected.

  •  Tags:  
  • c
  • Related