Reputation: 67
I met some problems when judging whether the user entered the right type of number.
I want to design a program that only applicable to enter int
type number. When the user enter another type (such as, double
, char
type), the system will output an error. However, when the user enter an illegal type of value, the system firstly output an enter instruction, then output the error sentence.
The code of this part are as follows:
for (int i = 0; i < nStudents; ++i) {
std::cout << "Please input the score of Student " << (i + 1) << ": ";
std::cin >> nArray[i];
if (!std::cin.good()) {
std::cout << std::endl << "The data type is not applicable. Please input integers!" << std::endl;
return 0;
}
}
When I enter an illegal value, the results are:
Please input the number of the students: 3
Please input the score of Student 1: 1.2
Please input the score of Student 2:
The data type is not applicable. Please input integers!
Could you please provide me a solution of this? Thanks!
Upvotes: 1
Views: 32
Reputation: 63471
Using the integer stream operator for this is much too simplistic. If input fails for any reason then you have to reset the error state, ignore some characters and continue reading.
What's more is that if something like a decimal point is encountered, that's just fine provided something that looked like an integer came before it. Of course, the next call will fail because you try to read an integer but the next character in the stream is '.'
.
This is what's happening in your case, and you're not even attempting to recover from the error.
In general, when you are requesting user input, the user is expected to press Enter after typing a value. So you can use line-based input for this. For that, you use std::string
with std::getline
. Once you have a line of input as a string, you can parse the required values from that string easily.
Here is a simple program that uses std::stoi
to convert a line of input to an integer. However, since "1.2" will still correctly parse as the integer value 1, some additional logic is added that allows only whitespace for any remaining characters.
#include <cctype>
#include <iostream>
#include <stdexcept>
#include <string>
int main()
{
std::string line;
while (std::getline(std::cin, line))
{
try {
size_t pos = 0;
int ival = std::stoi(line, &pos);
while (pos < line.size()) {
if (!std::isspace(line[pos]))
throw std::runtime_error("Malformed integer value");
++pos;
}
std::cout << "Integer read: " << ival << '\n';
}
catch(std::exception &e)
{
std::cerr << "Invalid input: " << line << '\n';
}
}
}
Live demo here: https://godbolt.org/z/vK1WxTh3n
Upvotes: 1