Home > Back-end >  C terminate called after throwing an instance of 'std::invalid_argument'
C terminate called after throwing an instance of 'std::invalid_argument'

Time:09-19

I just wrote this program. The test case I am using is 541. It is supposed to reverse the 541 into 154, then subtract 541 and 154, to get 396 then reverse that into 693. After that it is supposed to add 396 and 693 to get 1089. In the last three lines of code, I am trying to convert the strings into ints so I can add the last two numbers but I am getting this error. The code has to be done in this specific way for my class.

#include <iostream>
#include <string>
#include <algorithm>

/**
* main application starting point
* @return integer (0=SUCCESS)
*/

int main() {

    //prompts user to input a three-digit number
    std::string threeDigitNum;
    std::cout << "Enter a 3-digit number, where the first and last digit differ by at least one" ;
    std::cin >> threeDigitNum;

    //uses a for loop to output the reverse of the first number
    std::string threeReversed;
    int control = 0;
    for(int i = 2; i >= 0; i--){
        threeReversed[control] = threeDigitNum[i];
        control  ;
    }
    std::cout << threeDigitNum[2]  threeDigitNum[1]  threeDigitNum[0] << std::endl;

    //converts the numbers in the strings to integers
    //displays the differnce of the first and second number
    int firstNum = std::stoi(threeDigitNum);
    int secondNum = std::stoi(threeReversed);
    std::cout << firstNum - secondNum << std::endl;

    std::string thirdNum;
    thirdNum = std::to_string(firstNum - secondNum);
    std::string thirdNumReverse;
    for(int i = thirdNum.length(); i >= 0; i--){
        thirdNumReverse = thirdNumReverse   thirdNum[i];
    }
    std::cout << thirdNumReverse << std::endl;

    int fourthNum = std::stoi(thirdNum);
    int fifthNum = std::stoi(thirdNumReverse);
    std::cout<< fourthNum   fifthNum;








    return 0;
}

CodePudding user response:

Here's a hint:

std::string thirdNumReverse;
for(int i = thirdNum.length(); i >= 0; i--){
    thirdNumReverse = thirdNumReverse   thirdNum[i];
}

If the length of thirdNum is 3, then the valid indices are from [2..0]. But yor code enumerates a different range of indices.

CodePudding user response:

You are creating an empty string

std::string threeReversed;

and then you try to write into that empty (!) string using the subscript operator (using positions which don't exist in that string).

threeReversed[control] = threeDigitNum[i];

If you want to reverse a string, you can use a C Standard Library algorithm:

std::string threeReversed{ threeDigitNum };
std::reverse(threeReversed.begin(), threeReversed.end());

Later in the code, you have the same issue again for thirdNumReverse.

You are at a point where you want to learn how to debug small programs.

You may also want to use smaller methods which you can test on their own. See how short your code can become when you use a method that does the number reversing process for you:

#include <iostream>
#include <string>
#include <algorithm>
#include <cassert>
int reverse(int i)
{
    std::string s = std::to_string(i);
    std::reverse(s.begin(), s.end());
    return std::stoi(s);
}

int main() {
    assert(reverse(541) == 145);
    int threeDigitNum{541};
    int threeReversed = reverse(threeDigitNum);
    std::cout << threeReversed << std::endl;
    std::cout << threeDigitNum - threeReversed << std::endl;
    int thirdNum = threeDigitNum - threeReversed;
    int thirdNumReverse = reverse(thirdNum);
    std::cout << thirdNumReverse << std::endl;
    std::cout << thirdNum   thirdNumReverse;
    return 0;
}

CodePudding user response:

There are 2 errors in your code :

  • Error 1 : Creating empty string, but accessing other indices.
     std::string threeReversed;
     int control = 0;
     for(int i = 2; i >= 0; i--){
         threeReversed[control] = threeDigitNum[i];
         control  ;
     }

change above code as you already did while calculating thirdNumReverse :

    std::string threeReversed;
    for(int i = 2; i >= 0; i--){
        threeReversed = threeReversed   threeDigitNum[i];
   
    }
  • Error 2 : indices are 0 based in c , so start from thirdNum.length() - 1 instead of thirdNum.length()
    for(int i = thirdNum.length(); i >= 0; i--){
        thirdNumReverse = thirdNumReverse   thirdNum[i];
    }

change above code as below :

    for(int i = thirdNum.length() - 1; i >= 0; i--){
        thirdNumReverse = thirdNumReverse   thirdNum[i];
    }

Note : This code can be improved but I am just pointing out the errors in your existing code. Not improving it.

  •  Tags:  
  • c
  • Related