Crash cycle?

9

I have a problem with a while cycle. I want my program to only accept 4-digit numbers, and, if the user enters one that is out of range, it will miss error.

I had done this, but I noticed that from a certain number of figures, the program ended up throwing only the error line. I'd like to know what I'm doing wrong.

#include iostream

int main()
{
    int a=1, b;
    std::cin >> b;
    while (b > 9999 || b < 1110) {
        std::cout << "\nE R R O R. Favor de ingresar un numero de cuatro digitos.\n";
        std::cin >> b;
    }
    std::cout << b;

    system("pause");
}
    
asked by Caro GS 26.02.2018 в 07:47
source

2 answers

6
  

but I noticed that from a certain number of figures, the program ended up throwing only the error line.

The numbers are stored in b , which is type int . The type int is a type of signed whole data. This type of data, 32 bits, uses a bit to store the sign and the remaining 31 to store the number itself.

That is, for 31 bits, the largest number it can support is: 2 ^ 31-1 = 2,147,483,647.

If you try to enter a larger number, cin will not be able to store it in the variable and this causes an error flag to be activated ... from that moment cin is blocked until you deal with the error.

The most usual thing in these cases is to clean the error flag and empty the input buffer:

while (b > 9999 || b < 1110) {
    std::cout << "\nE R R O R. Favor de ingresar un numero de cuatro digitos.\n";
    std::cin >> b;
    if( std::cin.fail() )
    {
      std::cin.ignore(std::numeric_limits<int>::max(),'\n');
      std::cin.clear();
    }
}

Where:

  • numeric_limits is a C ++ template that gives you information about the numeric types. In this case we are asking you for the highest value that can be stored in a variable of type int . numeric_limits is in the library limits .
  • cin.ignore discards input characters ... in this case it will discard everything there is until it encounters a line break (which will also be discarded). The first parameter indicates the number of bytes to be discarded ... hence we use numeric_limits ... we want to discard the maximum possible.
  • cin.clear resets the error flag, which makes cin available again to read new values.

EDITO

The problem with the previous answer is that it does not contemplate the case that an incorrect entry is entered in the first iteration. I do not like to repeat code, so a possible solution would be the following:

int main()
{
    int b;
    bool pedirNumero = true;
    while(pedirNumero)
    {
        std::cin >> b;
        pedirNumero = std::cin.fail() || b > 9999 || b < 1110;

        if( pedirNumero )
        {
          std::cout << "\nE R R O R. Favor de ingresar un numero de cuatro digitos.\n";
          std::cin.ignore(std::numeric_limits<int>::max(),'\n');
          std::cin.clear();
        }
    }
    std::cout << b;
}
    
answered by 26.02.2018 / 08:05
source
3

I would propose a change of strategy. Instead of capturing numbers, it captures strings of characters (the length limit of strings is as large as the computer's memory allows). With strings of characters you will not have any limit to the length of the input numbers.

Once the chain is captured you can check if it is of length 4 and if it consists of numbers:

std::string b;
std::cin >> b;
while ((b.length() != 4) || !std::all_of(b.begin(), b.end(), [](char c) { return std::isdigit(c) != 0; })) {
    std::cout << "\nE R R O R. Favor de ingresar un numero de cuatro digitos.\n";
    std::cin >> b;
}

The function std::all_of verifies that all the elements among the facilitated iterators comply with a condition, in this case we verify that all are numbers with std::isdigit , which returns 0 when the provided character is not a digit.

You can see the code working in Wandbox 三 へ (へ ਊ) へ ハ ッ ハ ッ .

    
answered by 26.02.2018 в 09:55