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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 4.94
moskitos80
 Аватар для moskitos80
39 / 39 / 0
Регистрация: 04.10.2011
Сообщений: 128
04.09.2012, 10:29     Сброс состояния буфера cin.clear #1
Всем привет. Пытаюсь контролировать ввод пользователя. Вопрос в следующем: почему очерёдность операций принципиальна :

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;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
04.09.2012, 11:43     Сброс состояния буфера cin.clear #2
А Вы понимаете зачем нужны эти функции? Зачем синхронизировать поток с буфером, если в нем до сих пор установлены флаги ошибки? Сначала делается сброс флагов ошибок ( cin.clear() ), потом уже синхронизация, что бы вывести символы из буфера, которые остались после некорректного ввода.
moskitos80
 Аватар для moskitos80
39 / 39 / 0
Регистрация: 04.10.2011
Сообщений: 128
04.09.2012, 12:01  [ТС]     Сброс состояния буфера cin.clear #3
Цитата Сообщение от Toshkarik Посмотреть сообщение
А Вы понимаете зачем нужны эти функции?
По поводу cin.sync(); в мане написано:
Синхронизация входного буфера с источником данных. Это фактически означает, что непрочитанные символы в буфере отбрасываются.
Здесь вместо cin.sync(); можно было так же использовать cin.ignore(10,'\n'); - эффект будет тот же.

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

Про флаги состояния есть особенность, при установленом каком-либо флаге кроме good, работа с потоком будет невозможна.
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
04.09.2012, 12:22     Сброс состояния буфера cin.clear #6
некоторые ф-ции(в т.ч. clear()) проверяют состояние потока, и если установлены биты ошибок - ничего не делают
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
04.09.2012, 12:28     Сброс состояния буфера cin.clear #7
Цитата Сообщение от igorrr37 Посмотреть сообщение
некоторые ф-ции(в т.ч. clear()) проверяют состояние потока, и если установлены биты ошибок - ничего не делают
igorrr37, это как же clear() ничего не делает, если она сбрасывает эти самые флаги?
В данном случае sync() ничего не делает, данные остаются в буфере, когда сбрасываются ошибки командой clear(), происходит опять попытка ввода cin >> num, но в буфере еще есть символы, те самые, оставшиеся при ошибочном вводе, и снова происходит ошибка ввода, и так по кругу.
moskitos80
 Аватар для moskitos80
39 / 39 / 0
Регистрация: 04.10.2011
Сообщений: 128
04.09.2012, 12:28  [ТС]     Сброс состояния буфера cin.clear #8
Цитата Сообщение от Toshkarik Посмотреть сообщение
А Вы как думаете, если из за этих данных, эти флаги ошибок и выставились?
Цитата Сообщение от kazak Посмотреть сообщение
Про флаги состояния есть особенность, при установленом каком-либо флаге кроме good, работа с потоком будет невозможна.
Цитата Сообщение от igorrr37 Посмотреть сообщение
некоторые ф-ции(в т.ч. clear()) проверяют состояние потока, и если установлены биты ошибок - ничего не делают
- Исчерпывающе. Спасибо господа.
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
04.09.2012, 12:31     Сброс состояния буфера cin.clear #9
Toshkarik, точно, имел ввиду sync
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.09.2012, 17:44     Сброс состояния буфера cin.clear #10
sync() не срабатывает в линукс.
C++
1
cin.ignore(numeric_limits<streamsize>::max(), '\n');
или так
C++
1
while (cin.get() != '\n');
moskitos80
 Аватар для moskitos80
39 / 39 / 0
Регистрация: 04.10.2011
Сообщений: 128
04.09.2012, 18:05  [ТС]     Сброс состояния буфера cin.clear #11
Благодарю alsav22 полезная информация.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.09.2012, 00:56     Сброс состояния буфера cin.clear
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
05.09.2012, 00:56     Сброс состояния буфера cin.clear #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;
};

Не по теме:

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

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

Текущее время: 19:27. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru