Как вы используете cin.fail() для проверки строки в C ?

#c

#c

Вопрос:

Я пытаюсь проверить, вводится ли ввод, который должен быть строкой, в виде строки букв, а не цифр. Вот что у меня есть:

     // Manufacturer
    cout << "Enter the manufacturer: " << endl;
    string newManufacturer;
    cin >> newManufacturer;
    while (cin.fail()) {
        cout << "Error! Invalid input." << endl;
        cout << "Enter the manufacturer: " << endl;
        cin.clear();
        cin.ignore(256, 'n');
        cin >> newManufacturer;
    }
    obj1.setManufacturer(newManufacturer);
  

Комментарии:

1. Строки могут содержать все символы, включая числа. Если вы хотите исключить числа, вам нужно будет проверить строку на их наличие самостоятельно.

2. Чтобы проверить, является ли отдельный символ числом или нет, вы можете использовать std::isdigit . Чтобы проверить, является ли отдельный символ буквой или нет, вы можете использовать std::isalpha

3. Просто в качестве примечания: вместо дублирования строк cout << "Enter the manufacturer: " << endl; и cin >> newManufacturer; вы можете использовать бесконечный цикл for(;;) (что эквивалентно while(true) ) и иметь строку if ( !cin.fail() ) break; внутри этого бесконечного цикла. Таким образом, дублирование кода не потребуется.

4. «вводится как строка букв, а не цифр» — должна ли строка состоять из символов, которые все являются 1. буквами или 2. не числами? Например, разрешено ли строке содержать следующие символы? amp;^$# -(

5. Каково фактическое правило, которое сообщает вам, является ли имя производителя допустимым или нет? В реальном мире существуют компании с номерами в названиях, например 3M.

Ответ №1:

Я предлагаю вам использовать следующий код:

 #include <iostream>
#include <string>
#include <cctype>

int main()
{
    std::string newManufacturer;

    for (;;) //infinite loop
    {
        //prompt user for input
        std::cout << "Enter the manufacturer: " << std::flush;
        std::cin >> newManufacturer;

        //fall through to label "input_invalid" if stream extraction failed
        if ( !std::cin.fail() )
        {
            //verify that input consists completely of letters
            for ( char amp;c : newManufacturer )
            {
                if ( !std::isalpha( c ) )
                    goto input_invalid;
            }
            break;
        }

    input_invalid:
        //print error message and prepare stream for next input attempt
        std::cout << "Error! Invalid input." << std::endl;
        std::cin.clear();
        std::cin.ignore( 256, 'n' );
    }

    std::cout << "The input is valid." << std::endl;

    //do something with the input
}
  

Обычно вы не должны использовать goto операторы, если их можно избежать. Однако я не вижу способа избежать этого, не вызывая значительного дублирования кода.