It depends on what you understand by mistake, you are already avoiding it!
Where is the error?
By default, when an object in the family std::basic_istream
(as std::cin
) you give it to read something different from the input you give it, it does not throw an error. Depending on the version of the C ++ standard that your compiler follows, suppose this code:
int a = 11111;
int b = 22222;
std::cout << "Pon un valor numérico: ";
std::cin >> a;
std::cout << "Pon un valor numérico: ";
std::cin >> b;
std::cout << "El valor a es: " << a << '\n'
<< "El valor b es: " << b << '\n';
For this input data:
Pon un valor numérico: 1
Pon un valor numérico: patata
It will behave as follows:
- In pre-C ++ 11 standards, when a formatted reading fails, the input data remains unchanged.
- In standards after C ++ 11, when a formatted reading fails, the input data gets the value
0
.
So, according to the standard your compiler follows, you'll get these outputs:
Anterior a C++11
El valor a es: 1
El valor b es: 22222
C++11 o superior
El valor a es: 1
El valor b es: 0
There is no error in sight, but we can look for it.
However, in both cases, given that an incorrect data reading will have occurred, the data flow will establish the flag of failures to true value, you can check this flag with the function std::basic_ios::fail
:
int leer_valor()
{
int resultado;
while (true)
{
std::cout << "Pon un valor numérico: ";
std::cin >> resultado;
if (!std::cin.fail())
return resultado;
std::cout << "Algo ha fallado al leer\n";
std::cin.clear();
}
}
int a = leer_valor();
int b = leer_valor();
std::cout << "El valor a es: " << a << '\n'
<< "El valor b es: " << b << '\n';
In the example, the leer_valor
function would infinitely ask the user for values until the std::cin
reading is correct. It is important to erase the flag of failure with std::basic_ios::clear
because if not, subsequent readings would fail even being correct.
Do you want mistakes? You will have mistakes!
By default, when an object in the family std::basic_istream
(as std::cin
) you give it to read something different from the input you provide it, it does not throw an error but we can configure it to throw exceptions in case of erroneous reading using the function std::basic_ios::exceptions
:
int a = 11111;
int b = 22222;
std::cin.exceptions(std::ios_base::failbit);
try
{
std::cout << "Pon un valor numérico: ";
std::cin >> a;
std::cout << "Pon un valor numérico: ";
std::cin >> b;
}
catch (std::ios_base::failure &error)
{
std::cout << "Algo ha pasado al leer!";
}
std::cout << "El valor a es: " << a << '\n'
<< "El valor b es: " << b << '\n';
Although apparently this option is not very popular.
What if you type a double
?.
Reading a double
on an integer using the standard input will not produce any errors, nor will it set the fault flags nor throw exceptions if you set it to do so. Simply will assign the entire part of the entry number to the given int
variable. Which does not seem very problematic. But if you really need it, it would be more appropriate to read the entry as text and check that all the characters are numeric:
int leer_valor()
{
std::string lectura;
std::locale l("");
while (true)
{
std::cout << "Pon un valor numérico: ";
std::cin >> lectura;
if (std::all_of(lectura.cbegin(), lectura.cend(), [&l](auto v) { return std::isdigit(v, l); }))
return std::stoi(resultado);
std::cout << "Algo ha fallado al leer\n";
}
}
int a = leer_valor();
int b = leer_valor();
std::cout << "El valor a es: " << a << '\n'
<< "El valor b es: " << b << '\n';
The previous example uses the algorithm that verifies that all the data of a collection fulfills a function, in this case all the data of the read chain must comply with std::isdigit
so alphabetical values or decimal values will not pass the filter. Keep in mind that unless something strange happens, reading from console to a text variable will never fail.
Conclusion.
If the user types a letter instead of a whole number you can control it by reading the error flags but if you type a double
instead of a int
it is necessary to save in a text variable and analyze it.