newbie
newbie

Reputation: 15

how to insert only digits in a string

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

Answers (3)

dixit_chandra
dixit_chandra

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

Ted Lyngmo
Ted Lyngmo

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 chars 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

user15401571
user15401571

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 chars: https://www.techonthenet.com/ascii/chart.php

Upvotes: 1

Related Questions