web-dev-qa-db-fra.com

La vérification du flux d'entrée cin produit un entier

Je tapais ceci et il demande à l'utilisateur de saisir deux entiers qui deviendront alors des variables. À partir de là, il effectuera des opérations simples. 

Comment faire en sorte que l'ordinateur vérifie si ce qui est entré est un entier ou non? Et si non, demandez à l'utilisateur de taper un entier. Par exemple: si quelqu'un entre "a" au lieu de 2, il leur dira de ressaisir un nombre.

Merci

 #include <iostream>
using namespace std;

int main ()
{

    int firstvariable;
    int secondvariable;
    float float1;
    float float2;

    cout << "Please enter two integers and then press Enter:" << endl;
    cin >> firstvariable;
    cin >> secondvariable;

    cout << "Time for some simple mathematical operations:\n" << endl;

    cout << "The sum:\n " << firstvariable << "+" << secondvariable 
        <<"="<< firstvariable + secondvariable << "\n " << endl;

}
12
user2766546

Vous pouvez vérifier comme ceci:

int x;
cin >> x;

if (cin.fail()) {
    //Not an int.
}

De plus, vous pouvez continuer à entrer jusqu'à ce que vous obteniez un int via:

#include <iostream>



int main() {

    int x;
    std::cin >> x;
    while(std::cin.fail()) {
        std::cout << "Error" << std::endl;
        std::cin.clear();
        std::cin.ignore(256,'\n');
        std::cin >> x;
    }
    std::cout << x << std::endl;

    return 0;
}

EDIT: Pour répondre au commentaire ci-dessous concernant l’entrée, comme 10abc, on pourrait modifier la boucle pour accepter une chaîne en tant qu’entrée. Puis, recherchez dans la chaîne tout caractère autre qu'un nombre et gérez cette situation en conséquence. Il ne faut pas effacer/ignorer le flux d'entrée dans cette situation. En vérifiant que la chaîne ne contient que des chiffres, convertissez-la en un entier. Je veux dire, c'était juste pour le moment. Il pourrait y avoir un meilleur moyen. Cela ne fonctionnera pas si vous acceptez les flottants/doubles (il faudrait ajouter "." Dans la chaîne de recherche).

#include <iostream>
#include <string>

int main() {

    std::string theInput;
    int inputAsInt;

    std::getline(std::cin, theInput);

    while(std::cin.fail() || std::cin.eof() || theInput.find_first_not_of("0123456789") != std::string::npos) {

        std::cout << "Error" << std::endl;

        if( theInput.find_first_not_of("0123456789") == std::string::npos) {
            std::cin.clear();
            std::cin.ignore(256,'\n');
        }

        std::getline(std::cin, theInput);
    }

    std::string::size_type st;
    inputAsInt = std::stoi(theInput,&st);
    std::cout << inputAsInt << std::endl;
    return 0;
}
24
Chemistpp

Il existe une fonction dans c appelée isdigit(). Cela vous ira très bien. Exemple:

int var1 = 'h';
int var2 = '2';

if( isdigit(var1) )
{
   printf("var1 = |%c| is a digit\n", var1 );
}
else
{
   printf("var1 = |%c| is not a digit\n", var1 );
}
if( isdigit(var2) )
{
  printf("var2 = |%c| is a digit\n", var2 );
}
else
{
   printf("var2 = |%c| is not a digit\n", var2 );
}

De ici

1
nook

Si istream ne parvient pas à insérer, il définira le bit d'échec.

int i = 0;
std::cin >> i; // type a and press enter
if (std::cin.fail())
{
    std::cout << "I failed, try again ..." << std::endl
    std::cin.clear(); // reset the failed state
}

Vous pouvez définir cela dans une boucle do-while pour obtenir le type correct (int dans ce cas) correctement inséré.

Pour plus d'informations: http://augustcouncil.com/~tgibson/tutorial/iotips.html#directly

1
Zac Howland

Hé, c'est une vieille question qui pourrait utiliser une meilleure réponse.

Les entrées utilisateur doivent être obtenues sous forme de chaîne puis tentative convertie vers le type de données souhaité. De manière pratique, cela vous permet également de répondre à des questions telles que «Quel type de données puis-je saisir?»

Voici une fonction que j'utilise beaucoup. D'autres options existent, comme dans Boost, mais le principe de base est le même: essayez d'effectuer la conversion de type chaîne → et observez le succès ou l'échec:

template <typename T>
std::optional <T> string_to( const std::string& s )
{
  std::istringstream ss( s );
  T result;
  ss >> result >> std::ws;      // attempt the conversion
  if (ss.eof()) return result;  // success
  return {};                    // failure
}

Utiliser le type optional n’est qu’un moyen. Vous pouvez également lever une exception ou renvoyer une valeur par défaut en cas d'échec. Tout ce qui fonctionne pour votre situation.

Voici un exemple d'utilisation:

int n;
std::cout << "n? ";
{
  std::string s;
  getline( std::cin, s );
  auto x = string_to <int> ( s );
  if (!x) return complain();
  n = *x;
}
std::cout << "Multiply that by seven to get " << (7 * n) << ".\n";

limitations et identification du type

Pour que cela fonctionne, bien sûr, il doit exister une méthode permettant d’extraire sans ambiguïté votre type de données d’un flux. C'est l'ordre naturel des choses en C++, c'est-à-dire que les choses se passent comme d'habitude. Donc pas de surprises ici.

La mise en garde suivante est que certains types en englobent d'autres. Par exemple, si vous essayez de faire la distinction entre int et double, commencez par vérifier int, car tout ce qui est converti en int est également un double.

1
Dúthomhas

Vous pouvez utiliser le nom de variable lui-même pour vérifier si une valeur est un entier ..__, par exemple:

#include <iostream>
using namespace std;

int main (){

int firstvariable;
int secondvariable;
float float1;
float float2;

cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;

if(firstvariable && secondvariable){
    cout << "Time for some simple mathematical operations:\n" << endl;

    cout << "The sum:\n " << firstvariable << "+" << secondvariable 
    <<"="<< firstvariable + secondvariable << "\n " << endl;
}else{
    cout << "\n[ERROR\tINVALID INPUT]\n"; 
    return 1; 
} 
return 0;    
}
0
user6090272