-1

My assignment is to take test grades of students in a class room and return the highest, lowest, and the average. I am currently debugging for error that could be entered by the user. I have successfully fixed issues when the user inputs characters for the decimal test score values. What I'm having trouble with is if the user inputs "4k" the program excepts the 4 as a valid input but still gives the error when the program shouldn't approve the score as a valid input but should error and prompt for only numeral values.

I'll provide an output example

heres the code segment:

for (int i = 0; i < students; i++)
      {

        cout << "Please enter a score: " << flush;
        cin >> array[i];
        do{

          if(cin.fail())
          {
            cin.clear();
            cout<<"Error, that's not a decimal number. Please reenter: ";
            std::cin.ignore(numeric_limits<streamsize>::max(), '\n' );
            cin >> array[i];
          }
        }while(cin.fail());

      }

Sample output error::

How many students are in class? 3
Please enter 3 scores
 - - - - - - - - - - -
Please enter a score: jkl
Error, that's not a decimal number. Please reenter: jkl
Error, that's not a decimal number. Please reenter: 4k
Please enter a score: Error, that's not a decimal number. Please reenter: 0
Please enter a score: 3
4
0
3
The worstest score in the class is: 0
The bestest score in the class is: 4
The average score is: 2.33333

1 Answers1

0

Note: Based on your tags, I'm going to assume that you are using c++11. If not this answer wont work.

Using what you already have, try the following method to get the user input:

#include <iostream>
#include <string>
#include <limits>
#include <stdexcept>

double getValidInput()
{
    // Some variables for controlling how this works
    std::string user_input ;    // Used to store input
    bool bad_input(true) ;      // Set to true when the input is good
    double value(0.0) ;         // Value that will be returned
    size_t pos(0) ;             // Tells us when all of user_input was useable

    cout << "Please enter a score: " << flush ;
    cin >> user_input;

    // Now do the thing
    while (bad_input) {

        try {
            // Note that this may return an invalid string->double conversion
            value = std::stod(user_input, &pos) ;
        } catch (std::invalid_argument & err) {
            // The input isnt a number that can be converted
            // to a double
            pos = 0 ;
        }

        // If the entire string was converted then all is good!
        if (pos == user_input.size()){
            bad_input = false ;
        } else {
            cout<<"Error, that's not a decimal number. Please reenter: ";
            std::cin.ignore(numeric_limits<streamsize>::max(), '\n' );
            cin >> user_input ;
        }
    }

    return value ;
}

Ok, so what does all of this do? Lets start with

    try {
        // Note that this may return an invalid string->double conversion
        value = std::stod(user_input, &pos) ;
    } catch (std::invalid_argument & err) {
        // The input isnt a number that can be converted
        // to a double
        pos = 0 ;
    }

The user provides you with a string and you want to get a number from it (I'm assuming of type double). The above code is going to try to convert the user's input from a string to a double using std::stod(). Note that we also pass another variable pos which stores the length of the string that was able to be converted to a double.

Lets check your inputs:

  • In the case of your first input jkl a straight conversion to double cant be done. As a result std::stod throws an exception of type std::invalid_argument. The code catches that and sets pos=0. The following if statement notes that the length of the input string is longer than pos, so not all of the input was able to be converted, and the user has to try again.
  • In the case of your second input, 4k, std::stod can convert the string to a double up to the k, but at that point it stops. No exception is thrown, but pos is now one character smaller than the string, and again the user has to try again.

Now, you would insert this into your for-loop like so:

for (int i = 0; i < students; i++)
{
    array[i] = getValidInput() ;
}

Hope that helps!

Jvinniec
  • 616
  • 12
  • 18
  • Note that if this is a homework assignment, there may be parts of this answer which you havent covered in class yet, so if you use them you may get lower marks. – Jvinniec Sep 28 '16 at 20:35
  • If a teacher penalizes you for reading ahead in the material, grin and bear it and never do it in that class again, but quietly give the teacher the finger behind their back and make sure their craptastic education style is burned to the ground as soon as you've managed to get away with a good mark. The sooner we can get idiots like that out of the profession, the better. – user4581301 Sep 28 '16 at 20:56