С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.68/25: Рейтинг темы: голосов - 25, средняя оценка - 4.68
59 / 49 / 14
Регистрация: 23.02.2016
Сообщений: 433

cin.peek() и cin.putback()

27.10.2020, 01:37. Показов 4803. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вставляю 3 раза символ в поток ввода и метод peek() возвращает -1, как понимаю это eof, но если вставить 2 символа, то всё норм.

Мне непонятны 3 момента:

1) говорит ли это о том, что буфер по умолчанию выделяется на 2-3 байта для потока ввода (нереалистично как-то выглядит)?

2) почему reinterpret_cast<char> (cin.peek()) не отрабатывает?

3) почему in_avail() показывает 1, когда вставлено 3 символа в поток, а метод peek() не извлекает эти символы, а лишь просматривает очередной символ?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
using std::cout; using std::endl; using std::cin;
 
int main() {
 
    cin.putback('i'); // вставляет символ в поток ввода
    cin.putback('g'); // вставляет символ в поток ввода
    cin.putback('y'); // вставляет символ в поток ввода
    
        cout << char (cin.peek()) << endl;
 
    cout << cin.rdbuf()->in_avail(); // количество символов в буфере чтения
 
    return 0;
}
Добавлено через 49 минут
С вопросом 3 походу разобрался, судя по всему указатель не двигается и putback(symbol) просто перезаписывает один и тот же элемент потока, поэтому и элементов в потоке 1. Но почему он может два раза только переписать элемент не понял.

Добавлено через 49 минут
Неправильно понял как работает putback() https://www.youtube.com/watch?v=yMwA4u7eXEY
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.10.2020, 01:37
Ответы с готовыми решениями:

Как работает cin.peek, cin,get, cin.ignore, cin.clear?
Здравствуйте, товарищи и не товарищи!:) Я только начал изучать C++, а уже использую вещи, которые мне не понятны, и прошу объяснить, как...

Cin.putback
Для типа char char a; cin.putback(a); срабатывает, а как быть если тип std::string; string st; cin.putback(st); не...

Не работает cin.putback
Всем доброго времени суток! Собственно проблема в следующем фрагменте : //..... ...

4
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
27.10.2020, 12:57
Лучший ответ Сообщение было отмечено Timurs как решение

Решение

Цитата Сообщение от Timurs Посмотреть сообщение
1) говорит ли это о том, что буфер по умолчанию выделяется на 2-3 байта для потока ввода (нереалистично как-то выглядит)?
Для ввода с клавиатуры больше и не нужно
Цитата Сообщение от Timurs Посмотреть сообщение
2) почему reinterpret_cast<char> (cin.peek()) не отрабатывает?
Потому что после того, как ты попытаешься запихать туда лишние символы, поток перейдёт в состояние ошибки
C++
1
2
3
4
5
6
7
    cout << std::boolalpha << bool(cin) << endl;
    cin.putback('i'); // вставляет символ в поток ввода
    cout << std::boolalpha << bool(cin) << endl;
    cin.putback('g'); // вставляет символ в поток ввода
    cout << std::boolalpha << bool(cin) << endl;
    cin.putback('y'); // вставляет символ в поток ввода
    cout << std::boolalpha << bool(cin) << endl;
1
59 / 49 / 14
Регистрация: 23.02.2016
Сообщений: 433
02.11.2020, 00:56  [ТС]
oleg-m1973, спасибо. У меня цель была поместить символы в буфер, а затем посмотреть его размер. И ещё хотел перемещать как-то указатель по этому буферу.
Как понимаю символы в буфер можно поместить методом get(), он же сдвигает указатель на следующий элемент. Посмотреть размер буфера можно методом in_avail(). Как ходить по буферу не понял пока.

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

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <vector>
 
using std::cout; using std::endl; using std::cin;
 
int main() {
 
    char ch;
    
    // ввели строку abcde
    cin.get(ch);
 
    cout << "\n" << "method get() call #1" << "\n\n";
    
    // get 1
    cout << "read: " << ch << "\n";
    cout << "cur ptr: " << (char) cin.peek() << "\n";
    cout << "buf size: " << cin.rdbuf()->in_avail() << "\n";
 
    cout << "\n" << "method get() call #2" << "\n\n";
 
    // get 2
    cin.get(ch);
    cout << "read: " << ch << "\n";
    cout << "cur ptr: " << (char) cin.peek() << "\n";
    cout << "buf size: " << cin.rdbuf()->in_avail() << "\n";
 
    cout << "\n" << "method putback() call #1" << "\n\n";
 
    // putback 1
    cin.putback('i');
    cout << "cur ptr: " << (char) cin.peek() << "\n";
    cout << "buf size: " << cin.rdbuf()->in_avail() << "\n";
 
    cout << "\n" << "method putback() call #2" << "\n\n";
 
    // putback 2
    cin.putback('g');
    cout << "cur ptr: " << (char) cin.peek() << "\n";
    cout << "buf size: " << cin.rdbuf()->in_avail() << "\n";
 
    cout << "\n" << "method putback() call #3" << "\n\n";
 
    // putback 3
    cin.putback('y');
    cout << "cur ptr: " << (char) cin.peek() << "\n";
    cout << "buf size: " << cin.rdbuf()->in_avail() << "\n";
    
    return 0;
}
Code
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
28
29
30
31
32
33
34
35
36
37
38
abcde
 
method get() call #1
 
read: a
cur ptr: b
buf size: 5
 
// буфер |a|b|c|d|e|
 
method get() call #2
 
read: b
cur ptr: c
buf size: 4
 
// буфер |a|c|d|e|
 
method putback() call #1
 
cur ptr: i
buf size: 5
 
// буфер |a|i|c|d|e|
 
method putback() call #2
 
cur ptr: g
buf size: 6
 
// буфер |a|g|i|c|d|e|
 
method putback() call #3
 
cur ptr: y
buf size: 1
 
// буфер |y|
То есть как только он достигнет начала буфера, так буфер сбросится до одного символа.
Перепроверил на трех вызовах get() и четырёх вызовах putback(), тот же самый результат
Кликните здесь для просмотра всего текста
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <vector>
 
using std::cout; using std::endl; using std::cin;
 
int main() {
 
    char ch;
    
    // ввели строку abcde
    cin.get(ch);
 
    cout << "\n" << "method get() call #1" << "\n\n";
    
    // get 1
    cout << "read: " << ch << "\n";
    cout << "cur ptr: " << (char) cin.peek() << "\n";
    cout << "buf size: " << cin.rdbuf()->in_avail() << "\n";
 
    cout << "\n" << "method get() call #2" << "\n\n";
 
    // get 2
    cin.get(ch);
    cout << "read: " << ch << "\n";
    cout << "cur ptr: " << (char) cin.peek() << "\n";
    cout << "buf size: " << cin.rdbuf()->in_avail() << "\n";
 
    cout << "\n" << "method putback() get #3" << "\n\n";
 
    // get 3
    cin.get(ch);
    cout << "read: " << ch << "\n";
    cout << "cur ptr: " << (char) cin.peek() << "\n";
    cout << "buf size: " << cin.rdbuf()->in_avail() << "\n";
 
    cout << "\n" << "method putback() call #1" << "\n\n";
 
    // putback 1
    cin.putback('i');
    cout << "cur ptr: " << (char) cin.peek() << "\n";
    cout << "buf size: " << cin.rdbuf()->in_avail() << "\n";
 
    cout << "\n" << "method putback() call #2" << "\n\n";
 
    // putback 2
    cin.putback('g');
    cout << "cur ptr: " << (char) cin.peek() << "\n";
    cout << "buf size: " << cin.rdbuf()->in_avail() << "\n";
 
    cout << "\n" << "method putback() call #3" << "\n\n";
 
    // putback 3
    cin.putback('y');
    cout << "cur ptr: " << (char) cin.peek() << "\n";
    cout << "buf size: " << cin.rdbuf()->in_avail() << "\n";
 
    cout << "\n" << "method putback() call #4" << "\n\n";
 
    // putback 4
    cin.putback('k');
    cout << "cur ptr: " << (char) cin.peek() << "\n";
    cout << "buf size: " << cin.rdbuf()->in_avail() << "\n";
    
    return 0;
}


Кликните здесь для просмотра всего текста
Code
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
abcde
 
method get() call #1
 
read: a
cur ptr: b
buf size: 5
 
// буфер |a|b|c|d|e|
 
method get() call #2
 
read: b
cur ptr: c
buf size: 4
 
// буфер |a|c|d|e|
 
method putback() get #3
 
read: c
cur ptr: d
buf size: 3
 
// буфер |a|d|e|
 
method putback() call #1
 
cur ptr: i
buf size: 4
 
// буфер |a|i|d|e|
 
method putback() call #2
 
cur ptr: g
buf size: 5
 
// буфер |a|g|i|d|e|
 
method putback() call #3
 
cur ptr: y
buf size: 6
 
// буфер |a|y|g|i|d|e|
 
method putback() call #4
 
cur ptr: k
buf size: 1
 
// буфер |k|


Получается на 2 гета 3 путбэка и сброс, на 3 гета 4 путбэка и сброс. Ну и судя по всему на 1 гет 2 путбэка и сброс. Как будто запоминает сколько гетов было и делает на 1 путбэк больше. Причём я так и не понял почему первый гет не извлекает символ из потока.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.11.2020, 18:55
Цитата Сообщение от Timurs Посмотреть сообщение
oleg-m1973, спасибо. У меня цель была поместить символы в буфер, а затем посмотреть его размер. И ещё хотел перемещать как-то указатель по этому буферу.
Посмотри в сторону rdbuf
1
59 / 49 / 14
Регистрация: 23.02.2016
Сообщений: 433
02.11.2020, 18:59  [ТС]
Чет заглючило вчера, он же enter в поток добавил, так что всё там метод get() извлекает как и написано в документации.



Code
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
28
29
30
31
32
33
34
35
36
37
38
39
abcde
 
method get() call #1
 
read: a
cur ptr: b
buf size: 5
 
// буфер | |b|c|d|e|\n|
 
method get() call #2
 
read: b
cur ptr: c
buf size: 4
 
// буфер | | |c|d|e|\n|
 
method putback() call #1
 
cur ptr: i
buf size: 5
 
// буфер | |i|c|d|e|\n|
 
method putback() call #2
 
cur ptr: g
buf size: 6
 
// буфер |g|i|c|d|e|\n|
 
method putback() call #3
 
cur ptr: y
buf size: 1
 
// тут как бы выход за начало буфера и его последующий сброс
// буфер |y|
Получается на n гетов можно сделать n путбэков.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.11.2020, 18:59
Помогаю со студенческими работами здесь

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

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

Объясните функцию cin.peek
Ребята, привет! Я написала программу перевода минут и секунд в секунды и сделала защиту на буквы с помощью cin.peek. Не до конца поняла как...

Метод getline(cin, m) не срабатывает без cin.ignore() / Ревью кода
Почему в моем случае getline(cin, m) не срабатывает без cin.ignore() ? Если по коду есть какие-нибудь замечания, то просьба написать что не...

Продемонстрировать различие между вводом с помощью cin.Get и cin.Getline с тремя параметрами
Нужна помощь. Задача продемонстрировать различие между вводом с помощью cin.get и cin.getline с тремя параметрами, как из потока достать...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru