Reputation: 15
I have this code that should check if the user inputs 3 digits into a string variable:
std::string digits;
bool error = false;
do {
error = false;
std::cout << "Type 3 digits. (0 to 9)\n";
std::cin >> digits;
if (digits.size() != 3) {
std::cout << "\nError, you must type 3 digits.\n\n";
error = true;
}
else {
for (int i = 0; i < 3; i++) {
if (digits[i] < 0 || digits[i] > 9) {
std::cout << "\nError, you must type only digits. (0 to 9)\n\n";
error = true;
break;
}
}
}
} while (error == true);
This isn't giving any error but still it doesn't work, it correctly checks when user inserts more than 3 characters but even if the input is correct (123) it restarts the loop.
Upvotes: 0
Views: 332
Reputation: 478
I tried my best to keep the code minimal:
#include <string>
#include <iostream>
#include <algorithm>
int main() {
std::string digits;
bool error = true;
while (error){
std::cout << "Type 3 digits. (0 to 9)\n";
std::cin >> digits;
if (digits.size() not_eq 3 and (error = true))
std::cout << "\nError, you must type 3 digits.\n";
else if(std::any_of(digits.begin(), digits.end(), [](const auto& digit){ return not std::isdigit(digit);}) and (error = true))
std::cout << "\nError, you must type only digits. (0 to 9)\n\n";
else error = false;
}
}
Upvotes: 0
Reputation: 117298
if (digits[i] < 0 || digits[i] > 9)
is checking if digits[i]
has a character value less than 0 or greater than 9. The character '0'
is character 48 in most encodings Today (most notably, ASCII), so that check will not work. You should be checking if (digits[i] < '0' || digits[i] > '9')
- and there is already a function that does this. std::isdigit
.
You could also use the standard algorithm std::all_of
to check if all char
s in the string are in fact digits.
Example:
#include <algorithm> // std::all_of
#include <cctype> // std::isdigit
#include <iostream>
#include <string>
int main() {
std::string digits;
// A char to unsigned char casting lambda (to make isdigit safe)
auto isdigit_lambda = [](char ch) {
return std::isdigit(static_cast<unsigned char>(ch)) != 0; };
while(true) {
std::cout << "Type 3 digits. (0 to 9)\n";
if(not (std::cin >> digits)) {
// input failure - deal with that somehow
}
// if it has the correct size and all are digits, break out of the loop
if(digits.size() == 3 &&
std::all_of(digits.begin(), digits.end(), isdigit_lambda)) break;
std::cout << "\nError, you must type 3 digits.\n\n";
}
}
Upvotes: 1
Reputation:
Try this:
#include <string>
#include <iostream>
int main() {
std::string digits;
bool error = false;
do {
error = false;
std::cout << "Type 3 digits. (0 to 9)\n";
std::cin >> digits;
if (digits.size() != 3) {
std::cout << "\nError, you must type 3 digits.\n\n";
error = true;
}
else {
for (int i = 0; i < 3; i++) {
if (!isdigit(digits[i])) {
std::cout << "\nError, you must type only digits. (0 to 9)\n\n";
error = true;
break;
}
}
}
} while (error == true);
}
This uses the function isdigit()
to check if the current char
is a digit.
The reason your code before wasn't working is because the char (0 for this example, as it is a digit) '0'
actually has a character code different than 0. Quoting from https://www.tutorialspoint.com/ascii-nul-ascii-0-0-and-numeric-literal-0#:~:text=The%20ASCII%20NUL%20character%20is,The%20decimal%20equivalent%20is%2048
,
When programmer used '0' (character 0) it is treated as 0x30. This is a hexadecimal number. The decimal equivalent is 48.
Table of ascii char
s:
https://www.techonthenet.com/ascii/chart.php
Upvotes: 1