Home > Net >  How can you check if the user input begins with 0
How can you check if the user input begins with 0

Time:10-31

I managed to code the following program to reverse any number the user inputs. However, I need to make it so that it returns an error message if the user input begins with 0 (e.g. 0175). What would be the simplest way to do that?

#include<iostream>
using namespace std;

int main () 
{
char choice;
do {
int n, val, remainder, reverse = 0;
cout << "Enter a number that you would like to reverse: ";
cin >> n;
val = n; 
    
while (n != 0) 
{
    remainder = n % 10;
    reverse = reverse * 10   remainder;
    n = n / 10;
}
    
cout << "The reverse of " << val << " is " << reverse << endl;
cout << "Would you like to reverse another number? (Y/N) ";
cin >> choice;  
} while (choice == 'y' || choice == 'Y');
cout << "Thanks for using this program!"; 
}

 

CodePudding user response:

You should take it as a string and make the necessary check. You can take this for an example.

#include<iostream>
#include <string>

using namespace std;

int main () 
{
char choice;
do {
string n; int  val, remainder, reverse = 0;
cout << "Enter a number that you would like to reverse: ";
cin >> n;
if(n.at(0)=='0')
{
    cout<<"error";
    return 0;
}

val = atoi(n.c_str()); 
int temp = atoi(n.c_str()); 

while (temp != 0) 
{
    remainder = temp % 10;
    reverse = reverse * 10   remainder;
    temp = temp / 10;
}
    
cout << "The reverse of " << val << " is " << reverse << endl;
cout << "Would you like to reverse another number? (Y/N) ";
cin >> choice;  
} while (choice == 'y' || choice == 'Y');
cout << "Thanks for using this program!"; 
}

CodePudding user response:

If you analyze your requirements, then obviously you need to check a single digit, the first digit.

So a formatted input function, which converts the input characters for your into a number, will not work. WIth that, I mean int number; std::cin >> number will always try to convert, whatever digit sequence you give, to a number.

So, there are 2 possible solutions:

  • Read digit (a single character) by digit and build a number out of it (CAVEAT)
  • use none formatted input functions, like std::getline, make a validation and convert it to a string.

First solution would immediately validate the first digit after input and could give an immediate result. The 2nd solution is even more simpler, because you could could additionally use build in string function.

But, solution 1 will not work, because you cannot read single characters from std::cin in standard C . Input is buffered by C and the terminal. Please read for example here. Maybe astonishing, but also somehow logical. The user wants to input something, and, if there was a typo, press the backspace button, and after everything done, press enter.

So, the only viable solution for you is to read the number as a string. Then you may either convert it to a number and use your algorithm, or, use existing functions, like std::reverse or reverse iterators.

In any case, a lot of error checking must be done.

Please see below an example with all kinds of error checking:

#include <iostream>
#include <cctype>
#include <climits>
#include <string>

int main() {

    // We need a indicator, if an input is valid or not
    bool inputNumberIsValid{};

    // Loop. unitl the input number is valid
    do {

        // Instruct user on what to do
        std::cout << "\n\nEnter a number that you would like to reverse:\n";

        // Assum for the moment, taht the input is valid
        inputNumberIsValid = true;

        // This is the number we eventually want to have.
        unsigned int number{};

        // Read a number as string and check, if that worked
        std::string numberAsString{};
        if (not std::getline(std::cin, numberAsString)) {

            // Problem with input, reported by getline or better said std::cin
            std::cerr << "\n*** Error: Problem with input\n";;
            inputNumberIsValid = false;
            break;

        }
        else {
            // Now, we have a string to work with. In the beginning, we want to check for leading 0s
            bool checkForLeadingZeroes{ true };

            // Iterate over all characters in the input string and check for all error cases
            for (const char c : numberAsString) {

                // Only digits are allowed 
                if (not std::isdigit(c)) {

                    // Problem found. Show error message, indicate an invalid input and stop loop
                    std::cerr << "\n*** Error: Only digits are allowed\n";;
                    inputNumberIsValid = false;
                    break;
                }
                else {

                    // Check for a leading 0
                    if (checkForLeadingZeroes and c == '0') {

                        // Problem found. Show error message, indicate an invalid input and stop loop
                        std::cerr << "\n*** Error: Leading 0s are not allowed\n";;
                        inputNumberIsValid = false;
                        break;
                    }
                    else {
                        // Valid number. Convert digit characters to a number
                        number = number * 10;
                        number  = (c - '0');

                        // If the number is too big
                        if (number >= std::numeric_limits<unsigned int>::max() / 10) {

                            // Problem found. Show error message, indicate an invalid input and stop loop
                            std::cerr << "\n*** Error: Number is too big\n";
                            inputNumberIsValid = false;
                            break;
                        }
                    }
                }
                // After we did the forst check for leading 0es, we will no longer check 0s at all
                checkForLeadingZeroes = false;
            }
        }
        // OK, number rerad. If it is valid
        if (inputNumberIsValid) {

            // Then reverse the number
            unsigned int temp {static_cast<unsigned int>(std::stoul(numberAsString))};
            unsigned int reversedNumber{};
            while (temp != 0) {
                const unsigned int remainder = temp % 10;
                reversedNumber = reversedNumber * 10   remainder;
                temp = temp / 10;
            }

            // And show the final result
            std::cout << "\n\nThe reversed number is:  " << reversedNumber << '\n';
        }
    } while (not inputNumberIsValid);
}

This is a surprisingly long piece of code.

Please remember: Reading from std::cin is very complex and error prone.


By the way. In C you would do it more efficiently.

Please see below one of many possible examples:

#include <iostream>
#include <cctype>
#include <climits>
#include <string>
#include <algorithm>
#include <iterator>

int main() {

    // Loop. unitl the input number is valid
    for (bool numberIsValid{}; not numberIsValid;) {

        // Instruct user on what to do
        std::cout << "\n\nEnter a number (digits only, no leading 0es) that you would like to reverse:\n";

        // Read a number as string and check, if it is valid
        if (std::string numberAsString{}; std::getline(std::cin, numberAsString) and
            not numberAsString.empty() and
            std::all_of(numberAsString.begin(), numberAsString.end(), std::isdigit) and
            not (numberAsString[0] == '0') and
            numberAsString.size() < std::numeric_limits<unsigned int>::digits10)
        {
            // Number is valid
            numberIsValid = true;
            std::cout << "\n\nReverse number is:\t ";
            std::copy(numberAsString.rbegin(), numberAsString.rend(), std::ostream_iterator<char>(std::cout));
        }
        else {
            std::cerr << "\nError: Invalid input\n\n";
        }
    }
}

To be compiled with C 17.

Only one if statement (with many "and"s) to check for any kind of error.

Using "std::algorithms"

  •  Tags:  
  • c
  • Related