LINUX.ORG.RU

[C++] Как должен вести себя std::cin >> int с неправильным вводом?

 


0

0

Есть вот такой фрагмент:

int v;
for (;;){
    std::cout << "Вводите (0-конец): ";
    std::cin >> v;
    if (v==0) break;
    somefunction(v);
};
(Да, я знаю, что кто так пишет — сам виноват.)

Если вместо числа ввести текст, программа зацикливается. В каждом цикле раз за разом v присваивается какое-то значение без запроса на ввод с клавиатуры.

Это — нормальное поведение iostream?

★★★★★

мне лень смотреть, проверь у тебя может строка посимвольно считывается (т.е. char -> int, а строка - это массив char-ов)

и да, перепиши это гнилое место.

и да, дебаг - тоже не просто так придумали.

anonymous
()

непонятно, зачем впринципе так делать? Есть же getline...

najar
()
Ответ на: комментарий от anonymous

> у тебя может строка посимвольно считывается

Если я непонятно выразился, в каждом цикле v присваивается одно и то же значение. Даже если ввести один 1-байтовый символ, будет так же.

Переписывать не буду, т.к. эту программу применять не собираюсь. Это — пример из учебника :)

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

И кеш гугла тоже на прокси заблокирован.

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

Return Value
The object itself (*this).
When a value is being «extracted» it is not returned, but directly stored in the variable used as parameter.

Errors are signaled by modifying the internal state flags:

flag   error
eofbit   The end of the source of characters is reached during its operations.
failbit   The input obtained could not be interpreted as an element of the appropriate type.
Notice that some eofbit cases will also set failbit.
badbit   An error other than the above happened.

staseg ★★★★★
()
int v; 
for (;;){ 
    std::cout << "Вводите (0-конец): "; 
    if (!(std::cin >> v)) {
        puts("parse error");
        continue;
    } 
    if (v==0) break; 
    somefunction(v); 
};
Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Пробовал, как это работает? По-моему, оно тоже зациклится, если как-то не очистить буфер ввода iostream. Или puts его чистит?

question4 ★★★★★
() автор топика
Ответ на: комментарий от Legioner
int v;  
for (;!cin.eof();){  
    std::cout << "Вводите (0-конец): ";  
    if (!(std::cin >> v)) { 
        if (!cin.eof()) {
            puts("parse error"); 
            cin.clear();
            cin.ignore();
        }
        continue; 
    }  
    if (v==0) break;  
    somefunction(v);  
}; 
Eshkin_kot ★★
()

Если вместо числа ввести текст, программа зацикливается.

Т.к cin ожидает ввода intа (4 байта на х86), то при вводе символа, который занимает всего один байт, поток сбрасывается в невалидное состояние. ПОэтому надо проверять флажок ошибки, и, если что, сбрасывать поток

cin >> x;
if (cin.fail())
   {
     cin.clear();
     char c;
     cin >> c;
   }

Ккк-то так.

koirn
()
Ответ на: комментарий от koirn

koirn, cin это поток _форматированного_ ввода, он _текстовый_, поэтому он ждёт не четырёх байт int, а *ндцать ASCII цифр по одному байту на каждую цифру. Далее у себя внутри он проанализирует эти *ндцать прочитанных байт и преобразует их в бинарное представление int'а, если влезет, либо перейдёт в состояние «ошибка».

Eshkin_kot ★★
()
Ответ на: комментарий от Eshkin_kot

Может я и не прав, или не правильно выразился, но проблема в том, что он не может символ преобразовать в int.

koirn
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.