Заставить cin принимать выборочные входные данные [Turbo C++]

Не ненавидьте Турбо, я уже ненавижу свою школу!

Я хочу показать сообщение об ошибке, если вместо int или float в каком-либо файле, таком как возраст или процент, вводится символ. Я написал эту функцию:

template <class Type>
Type modcin(Type var) {
    take_input:  //Label
    int count = 0;
    cin>>var;
    if(!cin){
        cin.clear();
        cin.ignore();
        for ( ; count < 1; count++) { //Printed only once
            cout<<"\n Invalid input! Try again: ";
        }
        goto take_input;
    }
    return var;
}

но вывод нежелателен: ВЫХОДНОЙ ЭКРАН

Как предотвратить многократное повторение сообщения об ошибке? Есть ли лучший метод?


ПРИМЕЧАНИЕ. Пожалуйста, убедитесь, что мы говорим о TurboC++, я пытался использовать подход в этом вопрос, но даже после включения limit.h это не работает.


person Ankur Singh    schedule 10.10.2017    source источник
comment
Это пример неправильного использования goto. Не создавайте циклы с помощью goto. Используйте настоящие циклы.   -  person hyde    schedule 10.10.2017
comment
@hyde Я понимаю, что я использовал goto после того, как попробовал циклы for и do-while, я пробовал разные вещи, чтобы исключить множественные отпечатки. Я разместил код перехода, потому что это последняя попытка, которую я сделал.   -  person Ankur Singh    schedule 11.10.2017
comment
@AnkurSingh, вы переходите к каждому проходу, так что это бесконечный цикл ... Добавьте if, чтобы переход выполнялся, только если вы ввели неправильный ввод .... но for было бы лучше с, вероятно, гораздо меньшим количеством кода ...   -  person Spektre    schedule 11.10.2017
comment
@Spektre Я понимаю, но я пытался использовать время от времени. Это было давно, но я не мог избавиться от множественных отпечатков при вводе строк в консоль. Я даже пытался поставить цинвар; выйти из цикла и проверить его состояние в цикле while, но по некоторым причинам это также дало мне несколько выходов.   -  person Alpha Mineron    schedule 19.10.2017
comment
@AlphaMineron, ты тоже используешь TurboC++?   -  person Ankur Singh    schedule 21.10.2017
comment
@Spektre Goto не происходит на каждом шагу, он не бесконечен. Это происходит только при неправильном вводе. Goto находится внутри оператора if. Я исправил проблему с отступом.   -  person Ankur Singh    schedule 21.10.2017
comment
@AnkurSingh Я немного знаю и то, и другое.   -  person Alpha Mineron    schedule 22.10.2017


Ответы (1)


Вот фрагмент кода на C++.

template <class Type>
Type modcin(Type var) {
    int i=0;
    do{
        cin>>var;
        int count = 0;
        if(!cin) {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            for ( ; count < 1; count++) {  //Printed only once
                cout<<"\n Invalid input! Try again: ";
                cin>>var;
            }
        }
    } while (!cin);
    return var;
}

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

  • Он не может обрабатывать такие случаи, как «1fff», здесь вы просто получите 1 взамен. Я пытался решить это, но потом возник бесконечный цикл, когда я это исправлю, я обновлю код.
  • Он также не может эффективно работать в TurboC++. Я не знаю, есть ли альтернативы, но аргумент numeric_limits<streamsize>::max() выдает ошибку компилятора (ошибка «неопределенный символ» для numeric_limits и размера потока и ошибка «должен быть определен прототип» для max()) в Turbo C++ .

Итак, чтобы заставить его работать в Turbo C++. Замените аргумент numeric_limits<streamsize>::max() каким-нибудь большим значением int, например 100. Это сделает так, что буфер будет игнорироваться/очищаться только до тех пор, пока не будет достигнуто 100 символов или пока не будет нажата '\n' (кнопка ввода/символ новой строки).

РЕДАКТИРОВАТЬ


Следующий код может быть выполнен как на Turbo C++, так и на правильном C++. Комментарии предназначены для объяснения функционирования:

template <class Type>             //Data Integrity Maintenance Function
Type modcin(Type var) {           //for data types: int, float, double
    cin >> var;
    if (cin) {  //Extracted an int, but it is unknown if more input exists
         //---- The following code covers cases: 12sfds** -----//
        char c;
        if (cin.get(c)) {  // Or: cin >> c, depending on how you want to handle whitespace.
            cin.putback(c);  //More input exists.
            if (c != '\n') {  // Doesn't work if you use cin >> c above.
                cout << "\nType Error!\t Try Again: ";
                cin.clear();  //Clears the error state of cin stream
                cin.ignore(100, '\n');  //NOTE: Buffer Flushed <|>
                var = modcin(var);  //Recursive Repeatation
            }
        }
    }
    else {    //In case, some unexpected operation occurs [Covers cases: abc**]
        cout << "\nType Error!\t Try Again: ";
        cin.clear();  //Clears the error state of cin stream
        cin.ignore(100, '\n');  //NOTE: Buffer Flushed <|>
        var = modcin(var);
    }
    return var;

//NOTE: The '**' represent any values from ASCII. Decimal, characters, numbers, etc.
}
person Alpha Mineron    schedule 21.10.2017