0
void addNumbers(vector<double> &vec) {
    double add_num {};
    cout << "Enter an integer to add: ";
    cin >> add_num;
    vec.push_back(add_num);
    cout << add_num << " added" << endl;
}

The vector is empty, and I only want people to be able to add numbers into it, and whenever they try anything else it says "Invalid number".

The full code is below, and currently it just loops over and over saying "0.00 added" if I put something other than a number in lol

#include <iostream>
#include <vector>
#include <bits/stdc++.h>
#include <iomanip>
#include <cctype>
using namespace std;

char choice {};

char menu();
void print(vector<double>);
void mean(vector<double>);
void addNumbers(vector<double> &vec);
void smallest(vector<double>);
void largest(vector<double>);

char menu() {
    cout << "\nP - Print numbers" << endl;
    cout << "A - Add a number" << endl;
    cout << "M - Display mean of the numbers" << endl;
    cout << "S - Display the smallest number" << endl;
    cout << "L - Display the largest number" << endl;
    cout << "Q - Quit" << endl;
    cout << "\nEnter your choice: ";
    cin >> choice;
    choice = toupper(choice);
    return choice;
}

void print(vector<double> vec) {
    if (vec.size() != 0) {
    cout << "[ ";
    for (auto i : vec) {
        cout << i << " ";
    }
    cout << "]";
    }
    else {
        cout << "[] - the list is empty" << endl;
    }
}

void addNumbers(vector<double> &vec) {
    double add_num {};
    cout << "Enter an integer to add: ";
    cin >> add_num;
    vec.push_back(add_num);
    cout << add_num << " added" << endl;
}

void mean(vector<double> vec) {
    if (vec.size() != 0) {
    double result {};
    for (auto i : vec) {
        result += i;
    }
    cout << "The mean is " << result / vec.size() << endl;
    }
    else {
        cout << "Unable to calculate the mean - no data" << endl;
    }
}

void smallest(vector<double> vec) {
    if (vec.size() != 0) {
        cout << "The smallest number is " << *min_element(vec.begin(), vec.end()) << endl;
    }
    else {
        cout << "Unable to determine the smallest number - list is empty" << endl;
    }
}

void largest(vector<double> vec) {
    if (vec.size() != 0) {
        cout << "The largest number is " << *max_element(vec.begin(), vec.end()) << endl;
    }
    else {
        cout << "Unable to determine the largest number - list is empty" << endl;
    }
}

int main() {
    vector<double> vec {};
    bool done {true};
    cout << fixed << setprecision(2);

    do {
        menu();
        switch (choice) {
            case 'P':
                print(vec);
                break;
            case 'A': {
                addNumbers(vec);
                break;
            }
            case 'M': {
                mean(vec);
                break;
            }
            case 'S': {
                smallest(vec);
                break;
            }
            case 'L':
                largest(vec);
                break;
            case 'Q':
                cout << "Goodbye" << endl;
                done = false;
                break;
            default:
                cout << "Unknown selection, please try again" << endl;
        }
    } while (done == true);
    return 0;   
}
Kweebac
  • 11
  • 4
  • `cin >> add_num` will return false if they type something that can't be converted to a double like "dog". This answer should help: [https://stackoverflow.com/a/43080091/487892](https://stackoverflow.com/a/43080091/487892) – drescherjm Nov 14 '22 at 23:59
  • You can't restrict variables to getting their values from `std::cin`. Variables get their values from initialization, assignments, copies, or moves. You would have to modify the compiler or create a new language keyword to restrict variables to only getting their values from `std::cin`. – Thomas Matthews Nov 14 '22 at 23:59
  • 3
    Those include statements are very much an indicator that you don't know what you're writing. That gets problematic very quickly as programs get more complicated. The same can be said for forward declaring the functions, and then immediately implementing them. – sweenish Nov 15 '22 at 00:00
  • 1
    Since you are including all the `std` labels, keywords and names into the global namespace, be careful of your variable and function names. Better not to use `using namespace std;`. – Thomas Matthews Nov 15 '22 at 00:02
  • @sweenish: Sorry, I answering OP's title question. I have updated my comment. – Thomas Matthews Nov 15 '22 at 00:03
  • Here is a better example: [https://stackoverflow.com/questions/5131647/why-would-we-call-cin-clear-and-cin-ignore-after-reading-input](https://stackoverflow.com/questions/5131647/why-would-we-call-cin-clear-and-cin-ignore-after-reading-input) – drescherjm Nov 15 '22 at 00:08
  • 1
    [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) – Jesper Juhl Nov 15 '22 at 03:44
  • You cannot use `cin`, but have to create your own input function reacting to keyboard presses and ignoring non suitable characters. You could use `cin` with a `string`, but then the user could still enter wrong numbers, which your program would react to. – Sebastian Nov 15 '22 at 04:59
  • Why is it bad to forward declare functions? In the tutorial I'm watching he said you should always do it so that you can put your functions in whatever order you want, and it won't mess it up @sweenish – Kweebac Nov 15 '22 at 17:11
  • It is pointless to declare them and then immediately implement them right underneath. It's clutter. The order is something that takes about a minute in a toy program like this. It becomes moot in larger projects as things are generally declared first by design, like classes. You're going to find that most rules like that are not blanket recommendations, and there are plenty of exceptions. That is one aspect of becoming a software engineer, knowing which guidelines to adhere to and which to ignore *for a given situation*. – sweenish Nov 17 '22 at 04:27

3 Answers3

0
void addNumbers(vector<double>& vec) {
    double add_num{};
    string s;
    cout << "Enter an integer to add: ";
    cin >> s;
    try {
        add_num = stof(s);
    }catch (exception& e) {
        printf("error=%s\n", e.what());
        return;
    }
    vec.push_back(add_num);
    cout << add_num << " added" << endl;
}
shy45
  • 457
  • 1
  • 3
0

You need to check the return code of your extraction command cin >> add_num. And in general, you need to check the state of a stream after any IO operation.

So, what could happen? If you enter any invalid data, like for example "abc", then cin >> add_num will of course not work, and the state of the stream (cin) will set one of its failure bits. Please urgently check this.

And the failure will stay, unless you clear it. All further activities on cin will fail. SO, you need to call the clear() function of the stream. But this alone will not help. There may still be invalid characters in the input stream. And those must be eliminated.

You may use the ignore function for that:

cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');

And if you want to make sure to get the needed values, then you could come up with something like the below:

#include <iostream>
#include <vector>
#include <limits>
using namespace std;

void addNumbers(vector<double> &vec) {
    double add_num {};
    
    bool isValidNumber{};
    while (not isValidNumber) {
        
        cout << "Enter an integer to add: ";
        if (cin >> add_num) {
            isValidNumber = true;
        }
        else {
            cin.clear();
            cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
        }
    }   
    
    vec.push_back(add_num);
    cout << add_num << " added" << endl;
}


int main() {
    std::vector<double> values{};
    addNumbers(values);
}
A M
  • 14,694
  • 5
  • 19
  • 44
  • I'm pretty new to C++ so please excuse this stupid question but what exactly does `if (cin >> add_num)` mean, is it checking if a valid value (so a double) was entered? – Kweebac Nov 15 '22 at 12:17
-2
void addNumbers(vector<double> &vec) {
    int add_num=0;
    std::cout << "Enter an integer to add: ";
    if( std::cin >> add_num ) {
        vec.push_back((double)add_num);
        std::cout << add_num << " added" << std::endl;
    } else {
        std::cout << "It's not a valid number." << std::endl;
        std::cin.clear(); // to clear error status
        std::cin.ignore(1000,'\n');  // to ignore characters in buffer entered.
        return;
    }
}
sxu
  • 151
  • 5
  • It still keeps looping with this, and now when I add a double it displays "Unknown selection, please try again" once – Kweebac Nov 15 '22 at 02:43
  • Updated. Try again. – sxu Nov 15 '22 at 02:48
  • It doesn't loop anymore, but if I enter a double like 72.3 it adds 72 then enters .3 for the "Enter a choice" bit and thus displays "Unknown selection, please try again" – Kweebac Nov 15 '22 at 02:51
  • Because you promoted ```cout << "Enter an integer to add: ";```. Check your code. – sxu Nov 15 '22 at 03:05
  • If you want to read a double, use ```double add_num;``` and ```cout << "Enter a number to add:";``` – sxu Nov 15 '22 at 03:12