Home > Back-end >  how to handle input type integer when we enter character c
how to handle input type integer when we enter character c

Time:12-21

I have simple form and there is input type int. when i enter input birthYear and currentYear with character, the result is 0 and the program end before the input is filled.

char name[100], birthplace[100];
    int birthYear, currentYear, age;
    
    cout << "Name : ";
    cin.getline(name, 100);
    cout << "Birtyear : ";
    cin >> birthYear;
    cin.ignore();
    cout << "Current Year : ";
    cin >> currentYear;
    cin.ignore();
    cout << "Birthplace : ";
    cin.getline(birthplace, 100);

    age = currentYear - birthYear;
    
    cout << "=================" << endl;
    cout << "NAME : " << name << endl;
    cout << "AGE : " << age << endl;
    cout << "BIRTHPLACE : " << birthplace << endl;

i can't change the data type for birthYear and currentYear to string because it will be calculated.

i have try to convert change the data type for birthYear and currentYear to char and then convert it to int but when i enter character more than 1 the program not going well.

what i expect is when i enter character then the variable will set default value or the program show error message.

CodePudding user response:

I would use std::from_chars (since C 17) to read a string and convert it to a number:

  • std::from_chars allows you to check if the conversion from string to int had any errors (see return value ec in the example below), including extra characters (see return value ptr, pointing to the first character in the input string not matching an int).
  • You can take the conversion code out to a function and use it both for the birth year and the current year.
  • I would recommend using std::string instead of char[100] for reading input strings.
  • I wouldn't recommend mixing std::getline and cin >>.

[Demo]

#include <charconv>  // from_chars
#include <iostream>
#include <string>  // getline
#include <system_error>  // errc

int readYear(const std::string& text) {
    std::string yearStr{};
    int year{};
    for (;;) {
        std::cout << text;
        std::getline(std::cin, yearStr);
        std::cout << yearStr << "\n";
        auto [ptr, ec] = std::from_chars(yearStr.data(), yearStr.data()   yearStr.size(), year);
        if (ec != std::errc{} or ptr != yearStr.data()   yearStr.size()) {
            std::cout << "\tError: '" << yearStr << "' is not a correct year\n";
        } else {
            break;
        }
    }
    return year;
}

int main() {
    std::cout << "Name : ";
    std::string name{};
    std::getline(std::cin, name);
    std::cout << name << "\n";
    int birthYear{ readYear("Birth Year : ") };
    std::cout << birthYear << "\n";
    int currentYear{ readYear("Current Year : ") };
    std::cout << currentYear << "\n";
    std::cout << "Birth Place : ";
    std::string birthPlace{};
    std::getline(std::cin, birthPlace);
    std::cout << birthPlace << "\n";

    int age{ currentYear - birthYear };

    std::cout << "=================\n";
    std::cout << "NAME : " << name << "\n";
    std::cout << "AGE : " << age << "\n";
    std::cout << "BIRTHPLACE : " << birthPlace << "\n";
}

// Input:
//
//   John
//   abc
//   1980
//   2020def
//   2022
//   New York
//
// Output:
//
//  Name : John
//  Birth Year : abc
//      Error: 'abc' is not a correct year
//  Birth Year : 1980
//  1980
//  Current Year : 2020def
//      Error: '2020def' is not a correct year
//  Current Year : 2022
//  2022
//  Birth Place : New York
//  =================
//  NAME : John
//  AGE : 42
//  BIRTHPLACE : New York

CodePudding user response:

When extracting an integer from an input stream, operator>> will put the input stream into an error state if the input can't be converted to an integer. You need to check for this state and clear it before you can continue reading from the stream. For example:

int readInt(const char *prompt) {
    int value;
    do {
        cout << prompt << " : ";
        if (cin >> value) break;
        cout << "Invalid number entered! Try again\n";
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
    while (true);
    cin.ignore();
    return value;
}

...

char name[100], birthplace[100];
int birthYear, currentYear, age;
    
cout << "Name : ";
cin.getline(name, 100);

birthYear = readInt("Birth Year");
currentYear = readInt("Current Year");

cout << "Birthplace : ";
cin.getline(birthplace, 100);

age = currentYear - birthYear;
    
cout << "=================" << endl;
cout << "NAME : " << name << endl;
cout << "AGE : " << age << endl;
cout << "BIRTHPLACE : " << birthplace << endl;
  • Related