1

I have this piece of code which ensures that the user inputs a N-digit Number(With no leading zeroes). I am new to C++ but I feel the approach is correct. Please correct if anything is amiss.

#include <iostream>
#include <string>
#include <cmath>

std::string get_input(int n) {
    std::string guess;
    do
    {
        std::cout << "Enter a " << n << "-digit Number: ";
        std::cin >> guess;
    } while( (guess.length() != n) && (std::stoi(guess) / std::pow(10,n) == 0) );
    return guess; 
}


int main() {
    int n {};
    std::cout << "Enter N: ";
    std::cin >> n;
    std::string guess{get_input(n)};
    return 0; 
}

This program is accepting any length string(number). Which part of the solution seems wrong? PS: I use C++17(--std=c++17)

Edit: Add execution example

exec

schegu
  • 31
  • 8
  • 3
    It sounds like you may need to learn how to use a debugger to step through your code. With a good debugger, you can execute your program line by line and see where it is deviating from what you expect. This is an essential tool if you are going to do any programming. Further reading: [How to debug small programs](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) and [Debugging Guide](http://idownvotedbecau.se/nodebugging/) – NathanOliver Aug 24 '20 at 17:27
  • 1
    Please show an example execution of your program and explain how the behavior is different than what you want. – Code-Apprentice Aug 24 '20 at 17:27
  • 3
    Most likely, `std::pow` is causing your issues since [floating point math is weird](https://stackoverflow.com/questions/588004/is-floating-point-math-broken). – NathanOliver Aug 24 '20 at 17:28
  • Did you try debugging your code to see which part of your expressions yields a result that differs from what you expected? This is how you would narrow down and eventually solve the bug. Check out [this guide how to debug small programs](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) as well. – CherryDT Aug 24 '20 at 17:28
  • 2
    Yes, I am trying to go through the guide, Thanks. – schegu Aug 24 '20 at 17:31
  • Add some manual debugging: `cout << "n:" << n << " guess:" << guess.length() << " calc:" << ((std::stoi(guess) / std::pow(10,n)) << "\n";` – Eljay Aug 24 '20 at 17:32
  • How is the condition `(std::stoi(guess) / std::pow(10, n) == 0)` getting rid of leading zeros? I tried to run it with `n=3` and `guess=002`, but it failed to notice the leading zeros. Only with `guess=000` it prompted me to insert number again. – Giogre Aug 24 '20 at 18:02
  • @Lingo 2/1000 will be evaluated to zero. So, the do part of the do-while loop runs again. As the answers suggest, replace `&&` with `||` and try again. – schegu Aug 25 '20 at 03:59

2 Answers2

4

&& is not the correct logical operand. You need to use ||.

do
{
    std::cout << "Enter a " << n << "-digit Number: ";
    std::cin >> guess;
} while( (guess.length() != n) || (std::stoi(guess) / std::pow(10,n) == 0) );
//                             ^^

It might be easier to write and understand the code if you re-phrase the logic as:

bool isValidInput(string const& guess)
{
   return (guess.length() == n && (std::stoi(guess) / std::pow(10,n) != 0));
}

do
{
    std::cout << "Enter a " << n << "-digit Number: ";
    std::cin >> guess;
} while( !isValidInput(guess) );
cigien
  • 57,834
  • 11
  • 73
  • 112
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Yes, making it a function would help. Either way, thanks. I will upvote the answer after I have enough rep. Thank you. – schegu Aug 24 '20 at 17:42
2

Your logic is incorrect. You need to keep asking for input when the input string is either not the appropriate length OR there are some leading zeros in the input string.

So your condition should be:

do {
 // ...
} while ((guess.length() != n) || (std::stoi(guess) / std::pow(10,n) == 0))

Also, instead of using std::pow and std::stoi, you can check for leading zeros like this:

do {
 // ...
} while ((guess.length() != n) || (guess[0] == '0'))
cigien
  • 57,834
  • 11
  • 73
  • 112