-1

I am trying to get the addition done on the following method defined in my code, but after submitting the user input the program just return an exception instead of addition.

Exception:

terminate called after throwing an instance of 'std::invalid_argument' what(): stoi

This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.

Code:

#include <iostream>
#include <string>
using namespace std;
bool inputValidation_F(string userInput_VSTR1, string userInput_VSTR2)
{
    for (int inputChecker_V = 0; inputChecker_V < userInput_VSTR1.length() || userInput_VSTR1.length() && inputValidation_F; inputChecker_V ++)
        if (!(userInput_VSTR1[inputChecker_V] || userInput_VSTR2[inputChecker_V] >= 48 && userInput_VSTR1[inputChecker_V] || userInput_VSTR2[inputChecker_V] <= 57))
        return false;
    return true;
}
void mainMenu_F();
void userChoice_F();
void calCulations_F(double, double);
void resultAddition_F(double, double);
int main()
{
    mainMenu_F();
}
void mainMenu_F()
{
    cout << "Main Menu:" << '\n';
    cout << "-------------------------------" << '\n';
    cout << "Enter + for Addition" << '\n';
    cout << "-------------------------------" << '\n';
    cout << "Choose any Option from the List" << '\n';
    cout << "-------------------------------" << '\n';
    userChoice_F();
}
void userChoice_F()
{
    double addition_V_1;
    double addition_V_2;
    char uChoice_V;
    cin >> uChoice_V;
    switch (uChoice_V)
    {
    case '+':
    cout << "Addition: Enter the first value: "; cin >> addition_V_1;
    cout << "Addition: Enter the second value: "; cin >> addition_V_2;
    calCulations_F(addition_V_1, addition_V_2);
    }
}
void calCulations_F(double addition_V_1, double addition_V_2)
{
    string addition_V_1STR;
    string addition_V_2STR;
    addition_V_1 = stod (addition_V_1STR);
    addition_V_2 = stod (addition_V_2STR);
    bool additionChecker_F;
    additionChecker_F = inputValidation_F (addition_V_1STR, addition_V_2STR);
    if (!additionChecker_F)
        additionChecker_F = false;
    else resultAddition_F (addition_V_1, addition_V_2);
}
void resultAddition_F(double addition_V_1, double addition_V_2)
{
    double resultAddition_V = (addition_V_1 + addition_V_2);
    cout << "The result for the addition of the Entered values is: [" << resultAddition_V << "]" << '\n';
}
  • 1
    `string addition_V_1STR; stoi (addition_V_1STR);` You should initialize the variable to something first. – 001 Dec 31 '20 at 19:50
  • 6
    Shouldn't you be using `std::stod` instead? Also, you're converting empty strings. – sweenish Dec 31 '20 at 19:53
  • If you have make it work properly, please write an answer with the solution so I can accept it. – SeePlusPlus-Kid Dec 31 '20 at 19:57
  • 2
    `stoi` is for converting strings to integers. You won't be able to convert a double to a string with it. – John Dec 31 '20 at 20:16
  • 3
    I may have misunderstood, but the title `"Converting double to string..."` is at odds with what your code is trying to do -- namely convert a `std::string` to a `double`. Can you clarify what you're trying to achieve? – G.M. Dec 31 '20 at 20:28
  • @G.M. First I am taking user input and verifying if they are numbers sending the user input to result addition for calculation, else return false if not numbers. – SeePlusPlus-Kid Dec 31 '20 at 20:35
  • Your code has several places that need some checking. The most obvious logical mistake is in `void calCulations_F(double addition_V_1, double addition_V_2)` where you create two _empty_ strings and overwrite the two parameters, i.e. discard the user input. Also `inputValidation_F` is _really_ buggy. If I'm not mistaken the loops condition will _always_ be true and the `if` will always be false. – Lukas-T Dec 31 '20 at 20:36
  • I read the comments that shows me to use std::stod insread of std::stoi for doubles conversion to string, yes I agree this is true I must use std::stod. But here I am creating a temporary child conversion to pass the doubles as string in user input validation. I think I am not doing it wrong. ) – SeePlusPlus-Kid Dec 31 '20 at 20:40
  • @churill those are not empty because the cin is not cleared and they overrides in calCulations_F – SeePlusPlus-Kid Dec 31 '20 at 20:43
  • @SeePlusPlus-Kid -- You are stating what the problem cannot be, but you are having a problem with the `stoi`. So what do *you* think the problem is? – PaulMcKenzie Dec 31 '20 at 20:44
  • @SeePlusPlus-Kid How is `string addition_V_1STR;` anything but empty? You only read two doubles, store them in `addition_V_1` and `addition_V_2` and then overwrite them in `addition_V_1 = stoi (addition_V_1STR); addition_V_2 = stoi (addition_V_2STR);`, i.e. discard their old values. – Lukas-T Dec 31 '20 at 20:46
  • @PaulMcKenzie I think the problem is multiple overriding, I have tested with simple overriding and std:stoi works fine in simple overriding. – SeePlusPlus-Kid Dec 31 '20 at 20:47
  • Re. `"use std::stod insread of std::stoi for doubles conversion to string"`. Not quite. You've got things back to front. [`std::stod`](https://en.cppreference.com/w/cpp/string/basic_string/stof) converts an `std::string` into a `double`. So `std::stod(std::string("1.23"))` will return a `double` with the value `1.23`. – G.M. Dec 31 '20 at 20:47
  • 1
    @SeePlusPlus-Kid -- The big issue is that you have overcomplicated this whole thing. Why are you going through multiple levels of converting a single type? It's looking like a [Rube Goldberg](https://en.wikipedia.org/wiki/Rube_Goldberg_machine) set of manipulations. – PaulMcKenzie Dec 31 '20 at 20:49
  • @churill No they are not empty because they takes the input in inputValidation_F (addition_V_1STR, addition_V_2STR);entered to check numerics in inputValidation_F. – SeePlusPlus-Kid Dec 31 '20 at 20:52
  • @PaulMcKenzie I like to solve problems on extremely difficult way, I enjoy it ) and also it helps to boost my skills – SeePlusPlus-Kid Dec 31 '20 at 20:55
  • Do you have the wrong idea of what `addition_V_1 = stoi (addition_V_1STR);` does? It's converting the contents of the string `addition_V_1STR` to an integer and storing it in `addition_V_1`. Do you want to do this instead: `addition_V_1STR = std::to_string(addition_V_1);`, to convert `addition_V_1` to a string and store it in `addition_V_1STR`? – Kevin Dec 31 '20 at 22:08
  • @Kevin I have corrected it to std::stod and still it fails, the multiple overriding process is ignored. – SeePlusPlus-Kid Dec 31 '20 at 22:19
  • @SeePlusPlus-Kid `std::stod` vs `std::stoi` doesn't matter if what you actually want to do is convert a double to a string, since both are wrong. One converts a string to a double and the other converts a string to an integer. What you do *actually want to do*? – Kevin Dec 31 '20 at 22:35
  • @Kevin I am overriding from one function to another function and also the validation for numeric values is performed, if the validation is true the overriding process performed once again to calculate and print out the result. – SeePlusPlus-Kid Dec 31 '20 at 22:38
  • Your input validation can't work. See for example [this question](https://stackoverflow.com/questions/2075898/good-input-validation-loop-using-cin-c) for a better way. Your idea is to check if a string contains only digits 0-9. Maybe you should also allow a decimal point when you want to use doubles. But anyway, when you take a double and convert it to a string, how could it possibly contain anything else than digits and maybe a decimal point? Then how could `inputValidation_F` (after allowing decimal points) return anything but true? – Lukas-T Jan 01 '21 at 06:39
  • When you enter non-numeric data `cin >> addition_V_1;` will fail and simply store 0 to `addition_V_1`. It will not magically store a string in a double-variable. A will always be a double. You would need to take user input as string, then check it and only then convert it to double. You should follow the flow of your program, ideally in a [debugger](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) and check the contents of your variables. – Lukas-T Jan 01 '21 at 06:41
  • @churill Absolute solution ) thank you ) – SeePlusPlus-Kid Jan 04 '21 at 04:30

2 Answers2

2

terminate called after throwing an instance of 'std::invalid_argument' what(): stoi

The reason's here:

void userChoice_F() {
    .
    .
    // passing two 'double' parameters
    calCulations_F(addition_V_1, addition_V_2);
}

void calCulations_F(double addition_V_1, double addition_V_2)
{
    double resultAddition_V; // redundant
    string addition_V_1STR; // created, uninitialized
    string addition_V_2STR; // created, uninitialized

    // you're overriding the parameters here
    addition_V_1 = stoi (addition_V_1STR); // convert ? to double
    addition_V_2 = stoi (addition_V_2STR); // again here
                // better put stod() with a valid string here
    .
    .
}

Firstly, you're trying to convert the string into an integer and store it in a double, that's not a very useful idea, try std::stod() instead. But still that'll fail because addition_V_1STR and addition_V_2STR are empty (never assigned before), they're useless here.

Other problems:

  1. In the 6th line, you're comparing an integer to a long unsigned int, that's a bad practice.

  2. In the same line, userInput_VSTR1.length() && inputValidation_F will never be NULL.

  3. resultAddition_V is redundant here.

Rohan Bari
  • 7,482
  • 3
  • 14
  • 34
  • string addition_V_1STR; and string addition_V_2STR; doesn't need initialization because they are automatically initialized to the userinput using addition_V_1 and addition_V_2 and yes stod also fails because the user input is not passed to the calculation results from user input validation but at the same time the user input is successfully validated while it is asking for the second input if the first input is number. – SeePlusPlus-Kid Dec 31 '20 at 21:50
  • 2: In the same line, userInput_VSTR1.length() && inputValidation_F will never be NULL . This is another problem and easy to solve by using another bool to point to the first value bad index using array and then if the user input is null, the user input validation will be false. – SeePlusPlus-Kid Dec 31 '20 at 21:52
  • @SeePlusPlus-Kid they're nowhere automatically initialized in the provided code. – Rohan Bari Dec 31 '20 at 21:54
  • The "string userInput_VSTR1" is actually a temporary string child mask for "double addition_V_1" to pass the stored data from the cin of "double addition_V_1" to the "string userInput_VSTR1" in " inputValidation_F() " – SeePlusPlus-Kid Dec 31 '20 at 22:03
  • @SeePlusPlus-Kid reread the code, `additionChecker_F = inputValidation_F (addition_V_1STR, addition_V_2STR)` line is executed with those two unassigned strings, you're passing them as parameter without having values to process. – Rohan Bari Dec 31 '20 at 22:05
  • @RohanBari " bool additionChecker_F " overrides on the head of " bool inputValidation_F " for processing validation by taking doubles in the form of string child mask to pass the userInput. if they are uninitialized then how the validation process is done? Run the program and enter non-numeric data, it will return false, and if you enter numeric data it will ask you for the second number to store the data in the cin and again send and override to "resultAddition_F" while it also takes two new doubles. – SeePlusPlus-Kid Dec 31 '20 at 22:14
  • 1
    @SeePlusPlus-Kid the validation process was never done, i.e. the function call wasn't even reached correctly due to generating invalid argument exception. – Rohan Bari Dec 31 '20 at 22:15
  • @RohanBari On my end the validation process is done and then overriding stops in the top of resultAddition_F – SeePlusPlus-Kid Dec 31 '20 at 22:21
  • 1
    @SeePlusPlus-Kid _"On my end the validation process is done and then overriding stops in the top of resultAddition_F"_ This conflicts with your claims of having an exception from `stoi`. – Lukas-T Jan 01 '21 at 06:35
1

I think this solution will solve your Issues and Misunderstandings, Your code is edited and if you have any question, ask in comment or chat section, I will be happy to help you.

#include <iostream>
#include <string>
#include <limits>
using namespace std;
bool isvalid_(string);
bool inputValidation_F(string userInput_VSTR1, string userInput_VSTR2)
{
    for (int inputChecker_V = 0; inputChecker_V < userInput_VSTR1.length() || userInput_VSTR1.length() && inputValidation_F; inputChecker_V ++)
        if (!(userInput_VSTR1[inputChecker_V] || userInput_VSTR2[inputChecker_V] >= 48 && userInput_VSTR1[inputChecker_V] || userInput_VSTR2[inputChecker_V] <= 57))
        return false;
    return true;
}
void mainMenu_F();
void userChoice_F();
void calCulations_F(double, double);
void resultAddition_F(double, double);
int main()
{
    mainMenu_F();
}
void mainMenu_F()
{
    cout << "Main Menu:" << '\n';
    cout << "Enter + for Addition" << '\n';
    userChoice_F();
}
void userChoice_F()
{
    double addition_V_1, addition_V_2;
    char uChoice_V;
    cin >> uChoice_V;
    switch (uChoice_V)
    {
    case '+':
    cout << "Addition: Enter the first value: "; cin >> addition_V_1;
    cout << "Addition: Enter the second value: "; cin >> addition_V_2;
    while(!isvalid_("Ops! Entered invalid value, Try again."));
    calCulations_F(addition_V_1, addition_V_2);
    break;
    default:
        cout << "Invalid Choice," << '\n';
    }
}
void calCulations_F(double addition_V_1, double addition_V_2)
{
    if (!inputValidation_F)
        bool isvalid_ = 0;
    else resultAddition_F (addition_V_1, addition_V_2);
}
void resultAddition_F(double addition_V_1, double addition_V_2)
{
    double resultAddition_V = (addition_V_1 + addition_V_2);
    cout << "The result for the addition of the Entered values is: [" << resultAddition_V << "]" << '\n';
}
bool isvalid_(string err_msg)
{
    if(cin.rdstate())
    {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>:: max(), '\n');
        system("cls");
        cout << "Invalid number entry! Try again from the Beginning." << '\n';
        mainMenu_F();
        return false;
    }
    return true;
}
Ali-Baba
  • 198
  • 1
  • 9