Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 4.94
moskitos80
61 / 61 / 10
Регистрация: 04.10.2011
Сообщений: 217
Завершенные тесты: 1
#1

Сброс состояния буфера cin.clear - C++

04.09.2012, 10:29. Просмотров 2341. Ответов 11
Метки нет (Все метки)

Всем привет. Пытаюсь контролировать ввод пользователя. Вопрос в следующем: почему очерёдность операций принципиальна :

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
 
using namespace std;
 
int main()
{
    int num;
 
    while(1) {
 
        cout << endl << "Enter integer num . . . ";
        cin  >> num;
 
        if( cin ) {
            break;
        }
 
        cin.sync();    // Если здесь, то Вываливаемся в бесконечность
        cin.clear();
        //cin.sync();  // Если здесь, то всё ОК
 
        cout << endl << "Not valid integer num" << endl;
    }
 
    cout << endl << "Entered num " << num << endl;
    return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.09.2012, 10:29
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Сброс состояния буфера cin.clear (C++):

Защита от дурака при вводе текста с помощью: cin.get cin.clear cin.sync - C++
Доброго времени суток. На С++ учусь с недавних пор. Имеется стандартная &quot;защита от дурака&quot; на ввод. Не пойму предназначение cin.get() !=...

Объясните пожалуйста как работают cin.good(), cin.sync(), cin.clear() - C++
Такая проблема: сдаю в вуза лабораторные по программированию, писал все сам, до этого c++ не изучал, поэтому возникали некоторые проблемы....

Cin.clear cin.ignore - C++
Как использовать cin.clear и cin.ignore?

Cin.clear() не работает? - C++
Почему cin.clear() не работает как надо? ( не очищает поток ). Если мы вводим например 3 значения (123) то цикл срабатывает 3 раза. while...

cin.get() и cin.clear() - C++
В общем, занимаюсь по видео-урокам на ютубе, дошли до темы &quot;массивы&quot;. Суть программы - вывести наибольший и наименьший элемент (его...

Не очищается поток после cin.clear() - C++
Собственно есть программа записывающая данные в файл и считывающая их оттудова со всеми сопутствующими функциями (новая запись, обновление...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
04.09.2012, 11:43 #2
А Вы понимаете зачем нужны эти функции? Зачем синхронизировать поток с буфером, если в нем до сих пор установлены флаги ошибки? Сначала делается сброс флагов ошибок ( cin.clear() ), потом уже синхронизация, что бы вывести символы из буфера, которые остались после некорректного ввода.
moskitos80
61 / 61 / 10
Регистрация: 04.10.2011
Сообщений: 217
Завершенные тесты: 1
04.09.2012, 12:01  [ТС] #3
Цитата Сообщение от Toshkarik Посмотреть сообщение
А Вы понимаете зачем нужны эти функции?
По поводу cin.sync(); в мане написано:
Синхронизация входного буфера с источником данных. Это фактически означает, что непрочитанные символы в буфере отбрасываются.
Здесь вместо cin.sync(); можно было так же использовать cin.ignore(10,'\n'); - эффект будет тот же.

Про cin.clear(); я знаю, что этот метод просто сбрасывает биты ошибок, как они могут быть связаны с данными в буфере?
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
04.09.2012, 12:21 #4
Цитата Сообщение от moskitos80 Посмотреть сообщение
Здесь вместо cin.sync(); можно было так же использовать cin.ignore(10,'\n'); - эффект будет тот же.
Нет, нельзя было бы. sync() синхронизирует поток, а не игнорирует 10 символов.
Цитата Сообщение от moskitos80 Посмотреть сообщение
как они могут быть связаны с данными в буфере
А Вы как думаете, если из за этих данных, эти флаги ошибок и выставились?
kazak
3034 / 2355 / 155
Регистрация: 11.03.2009
Сообщений: 5,402
Завершенные тесты: 1
04.09.2012, 12:22 #5
Цитата Сообщение от moskitos80 Посмотреть сообщение
Здесь вместо cin.sync(); можно было так же использовать cin.ignore(10,'\n'); - эффект будет тот же.
Правда? А если в буфере останется 50 символов?

Про флаги состояния есть особенность, при установленом каком-либо флаге кроме good, работа с потоком будет невозможна.
igorrr37
1646 / 1274 / 133
Регистрация: 21.12.2010
Сообщений: 1,932
Записей в блоге: 7
04.09.2012, 12:22 #6
некоторые ф-ции(в т.ч. clear()) проверяют состояние потока, и если установлены биты ошибок - ничего не делают
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
04.09.2012, 12:28 #7
Цитата Сообщение от igorrr37 Посмотреть сообщение
некоторые ф-ции(в т.ч. clear()) проверяют состояние потока, и если установлены биты ошибок - ничего не делают
igorrr37, это как же clear() ничего не делает, если она сбрасывает эти самые флаги?
В данном случае sync() ничего не делает, данные остаются в буфере, когда сбрасываются ошибки командой clear(), происходит опять попытка ввода cin >> num, но в буфере еще есть символы, те самые, оставшиеся при ошибочном вводе, и снова происходит ошибка ввода, и так по кругу.
moskitos80
61 / 61 / 10
Регистрация: 04.10.2011
Сообщений: 217
Завершенные тесты: 1
04.09.2012, 12:28  [ТС] #8
Цитата Сообщение от Toshkarik Посмотреть сообщение
А Вы как думаете, если из за этих данных, эти флаги ошибок и выставились?
Цитата Сообщение от kazak Посмотреть сообщение
Про флаги состояния есть особенность, при установленом каком-либо флаге кроме good, работа с потоком будет невозможна.
Цитата Сообщение от igorrr37 Посмотреть сообщение
некоторые ф-ции(в т.ч. clear()) проверяют состояние потока, и если установлены биты ошибок - ничего не делают
- Исчерпывающе. Спасибо господа.
igorrr37
1646 / 1274 / 133
Регистрация: 21.12.2010
Сообщений: 1,932
Записей в блоге: 7
04.09.2012, 12:31 #9
Toshkarik, точно, имел ввиду sync
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.09.2012, 17:44 #10
sync() не срабатывает в линукс.
C++
1
cin.ignore(numeric_limits<streamsize>::max(), '\n');
или так
C++
1
while (cin.get() != '\n');
moskitos80
61 / 61 / 10
Регистрация: 04.10.2011
Сообщений: 217
Завершенные тесты: 1
04.09.2012, 18:05  [ТС] #11
Благодарю alsav22 полезная информация.
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
05.09.2012, 00:56 #12
Нашел более изящное и кроссплатформенное решение тут:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class ignoreline {
 public:
   ignoreline ( bool always_discard = false )
      : _always_discard ( always_discard ),
        _nread ( 0 )
   {
 
   }
 
   std::streamsize gcount() const {
      return _nread;
   }
 
   template <typename CharT>
   friend std::basic_istream<CharT>& operator>> ( std::basic_istream<CharT>& in, const ignoreline& manip ) {
      manip._nread = ignore_line ( in, manip._always_discard );
      return in;
   }
 
 private:
   bool _always_discard;
   mutable std::streamsize _nread;
};

Не по теме:

Так же там есть пример для паузы.

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.09.2012, 00:56
Привет! Вот еще темы с ответами:

Сброс буфера вывода - C++
Здравствуйте.Изучаю библиотеку ввода и вывода, познакомился тремя способами сброса буфера: endl, flush, ends. Могли бы вы привести...

Очистка всего буфера ввода (cin) - C++
Предположим у нас есть клиентское приложение, которое ожидает сообщение от сервера. При получении этого сообщения клиент должен отправить...

Очистка буфера ввода при работе с cin - C++
Добрый вечер! Пытаюсь научиться работать с классами, подскажите пожалуйста, что я делаю не так. В частности не работает функция enter,...

Почему не работает cin.clear() и как работает sync()? - C++
#include&lt;iostream&gt; #include&lt;cstring&gt; using namespace std; char*input(char*ch,int&amp;n){ cin.getline(ch,20); //cin.sync(); ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
05.09.2012, 00:56
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru