Het controleren van de cin-invoerstroom levert een geheel getal op

Ik was dit aan het typen en het vraagt de gebruiker om twee gehele getallen in te voeren die dan variabelen worden. Van daaruit voert het eenvoudige handelingen uit.

Hoe kan ik de computer laten controleren of het ingevoerde een geheel getal is of niet? En zo niet, vraag de gebruiker om een geheel getal in te voeren. Bijvoorbeeld: als iemand “a” invoert in plaats van 2, dan zal het hem vertellen een getal opnieuw in te voeren.

Bedankt

#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;
}

Antwoord 1, autoriteit 100%

Je kunt dit als volgt controleren:

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

Bovendien kun je input blijven krijgen totdat je een int krijgt 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: Om de onderstaande opmerking met betrekking tot invoer zoals 10abc aan te pakken, zou men de lus kunnen wijzigen om een string als invoer te accepteren. Controleer vervolgens de tekenreeks op elk teken en geen nummer en handel die situatie dienovereenkomstig af. Men hoeft in die situatie de invoerstroom niet te wissen/negeren. Controleer of de tekenreeks alleen maar getallen is, converteer de tekenreeks terug naar een geheel getal. Ik bedoel, dit was gewoon uit de losse pols. Er is misschien een betere manier. Dit werkt niet als u floats/doubles accepteert (u zou ‘.’ in de zoekreeks moeten toevoegen).

#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;
}

Antwoord 2, autoriteit 9%

Heh, dit is een oude vraag die een beter antwoord zou kunnen gebruiken.

Gebruikersinvoer moet worden verkregen als een tekenreeksen vervolgens poging tot conversienaar het gewenste gegevenstype. Handig is dat u hiermee ook vragen kunt beantwoorden als “welk type gegevens heb ik ingevoerd?”

Hier is een functie die ik veel gebruik. Er zijn andere opties, zoals in Boost, maar het uitgangspunt is hetzelfde: probeer de string → typeconversie uit te voeren en observeer het succes of de mislukking:

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
}

Het gebruik van het type optionalis slechts één manier. U kunt ook een uitzondering genereren of een standaardwaarde retourneren bij een fout. Wat werkt voor jouw situatie.

Hier is een voorbeeld van het gebruik ervan:

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";

beperkingen en type-identificatie

Om dit te laten werken, moet er natuurlijk een methode bestaan om uw gegevenstype ondubbelzinnig uit een stream te extraheren. Dit is de natuurlijke orde der dingen in C++ – dat wil zeggen, business as usual. Dus geen verrassingen hier.

Het volgende voorbehoud is dat sommige typen andere subsumeren. Als u bijvoorbeeld probeert onderscheid te maken tussen inten double, controleer dan eerst op int, aangezien alles wat wordt geconverteerd naar een intis ook een double.


Antwoord 3, autoriteit 3%

Er is een functie in c genaamd isdigit(). Dat zal je vast goed staan. Voorbeeld:

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 );
}

Van hier


Antwoord 4, autoriteit 3%

Als istream er niet in slaagt om in te voegen, zal het de faalbit instellen.

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
}

Je kunt dit instellen in een do-while-lus om het juiste type (in dit geval int) correct in te voegen.

Voor meer informatie: http://augustcouncil.com/~tgibson/tutorial/ iotips.html#rechtstreeks


Antwoord 5

U kunt de naam van de variabele zelf gebruiken om te controleren of een waarde een geheel getal is.
bijvoorbeeld:

#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;    
}

Antwoord 6

I liever gebruik <limits>om te controleren op een inttotdat afgelopen

.

# include & lt; iostream & gt;
#include & lt; limieten en gt; // std :: numeric_limits
met behulp van std :: cout, std :: endl, std :: cin;
int main () {
  int num;
  while ((CIN & gt;! & gt; num)) {// Controleer de Input formaat voor integer op de juiste manier
    cin.clear ();
    cin.ignore (std :: numeric_limits & lt; std :: streamsize & gt; :: max (), '\ n');
    cout & lt; & lt; "Ongeldige invoer Voer het nummer:.";
   };
  cout & lt; & lt; "Output =" & lt; & lt; num & lt; & lt; ENDL;
  retour 0;
}

Antwoord 7

Onder C++ 11 en later, heb ik het vond de std :: Stoi functie zeer nuttig zijn voor deze taak. Stoi gooit een invalid_argument uitzondering als conversie niet kan worden uitgevoerd. Dit kan worden gevangen en zoals in de demofunctie ‘getIntegerValue’ hieronder.

De Stoi functie heeft een tweede parameter ‘idx’ dat de positie van het eerste teken in de reeks na het nummer aangeeft. We kunnen de waarde in idx controleren tegen de stringlengte en vaststellen of er eigenschappen in de ingang dan het getal. Dit helpt bij het elimineren ingang als 10abc of een decimale waarde.

De enige geval waarin deze benadering niet wanneer er witruimte na het nummer van de invoer, dat wil zeggen de gebruiker veel ruimte binnengaat na het invoeren van het nummer. Om een ​​dergelijke zaak te behandelen, kan je de input string RTRIM zoals beschreven in dit bericht .

#include <iostream>
#include <string>
bool getIntegerValue(int &value);
int main(){
    int value{};
    bool valid{};
    while(!valid){
        std::cout << "Enter integer value: ";
        valid = getIntegerValue(value);
        if (!valid)
            std::cout << "Invalid integer value! Please try again.\n" << std::endl;
    }
    std::cout << "You entered: " << value << std::endl;
    return 0;
}
// Returns true if integer is read from standard input
bool getIntegerValue(int &value){
    bool isInputValid{};
    int valueFromString{};
    size_t index{};
    std::string userInput;
    std::getline(std::cin, userInput);
    try {
        //stoi throws an invalid_argument exception if userInput cannot be
        //converted to an integer.
        valueFromString = std::stoi(userInput, &index);
        //index being different than length of string implies additional
        //characters in input that could not be converted to an integer.
        //This is to handle inputs like 10str or decimal values like 10.12
        if(index == userInput.length()) isInputValid = true;
    }
    catch (const std::invalid_argument &arg) {
        ;       //you could show an invalid argument message here.
    }
    if (isInputValid) value = valueFromString;
    return isInputValid;
}

Antwoord 8

Je zou kunnen gebruiken:

int a = 12;
if (a>0 || a<0){
cout << "Your text"<<endl;
}

Ik ben er vrij zeker van dat het werkt.

Other episodes