Ввести двойной в переменную int, используя ошибку подключения istream - PullRequest
1 голос
/ 16 апреля 2019

Под windows10 и VS2017:

Я пытался прочитать двойное число 1.1 с клавиатуры с помощью istream и поместить его в переменную типа int, скажем temp. По причине temp равно 1, но istream, похоже, застрял в каком-то состоянии ошибки. В ожидании istream должен остановиться и дождаться ввода с клавиатуры, но он продолжает повторное чтение из буфера и на этот раз происходит ошибка.

Я проверил rdstate(), и он был равен 2 после 2-го раунда чтения из буфера. Я знаю, что это было ненормально, но почему?

Для репликации, запустите код, введите 1.1 в консоли и нажмите Enter, появится ошибка.


На самом деле, я использовал int32, чтобы попытаться сохранить double по некоторым причинам. Предполагается, что программа будет печатать правильный ввод с клавиатуры. Здесь действительный относится к тому, что ввод не должен превышать диапазон int32 или быть двойным / читаемым символом. В противном случае программа должна напечатать Invalid input на экране.

#include <iostream>

std::istream& f(std::istream &in) {
    int temp = 0;
    while(true) { 
        while (in >> temp) {
            if (temp == -1) {
                break;
            }
            std::cout << temp << std::endl;
        }
        if (in.eof()|| temp == -1) break;
        if (!in) {
            std::cout << "Invalid input"  << std::endl;
            in.clear();
            in.ignore(10000,32);
        }
    }
    in.seekg(0, std::ios::beg);
    return in;
}

int main(){
    std::cout << "Please input some integers and end with ^Z or -1" << std::endl;
    f(std::cin);
    return 0;
}

Ответы [ 2 ]

0 голосов
/ 16 апреля 2019

Помните, что когда вы читаете 1.1 с клавиатуры, вы читаете текст . Программа просматривает этот текст и решает, какое значение он представляет, в зависимости от типа переменной, в которую вы читаете. Если вы читаете в int, процедура ввода читает первый «1», затем видит «.», Который не может быть частью текстового представления int, и прекращает чтение. Ваша переменная получает значение 1. Если вы попытаетесь прочитать другой int из того же входного потока, это '.' немедленно остановит чтение, так как оно не может быть частью int, и попытка ввода не удалась.

Краткий ответ: не делай этого. Если введенный вами текст выглядит как число с плавающей точкой, считайте его как число с плавающей точкой.

0 голосов
/ 16 апреля 2019

Попробуйте это:

#include <iostream>

std::istream& f(std::istream &in) {
    std::string temp = "";
    while(true) { 
        while (in >> temp) {
            if (temp == "-1") {
                break;
            }
            std::cout << temp << std::endl;
        }
        if (in.eof()|| temp == "-1") break;
        if (!in) {
            std::cout << "Invalid input"  << std::endl;
            in.clear();
            in.ignore(10000,32);
        }
    }
    in.seekg(0, std::ios::beg);
    return in;
}

int main(){
    std::cout << "Please input some integers and end with ^Z or -1" << std::endl;
    f(std::cin);
    return 0;
}

Вы анализируете символ за символом из буфера. Вы не можете поместить символ в целое число. Вы предполагаете, что читаете 1.1 из потока, но вместо этого вы читаете 1, ., 1 из буфера, а . выдает ошибку. Приведенная выше часть работает, когда вы читаете символы и держите их в строке.

...