Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/29: Рейтинг темы: голосов - 29, средняя оценка - 4.55
1352 / 851 / 365
Регистрация: 26.02.2015
Сообщений: 3,799
1

Очистка потока

21.08.2016, 11:35. Показов 5654. Ответов 19

Author24 — интернет-сервис помощи студентам
Приветствую!

Есть метод класса, принимающий имя сотрудника (объект класса string) и его номер:

C++
1
2
3
4
5
6
7
8
9
void Employee::setData() {
    
    cout << "Введите имя: ";
    getline(cin, name);
    
    cout << "Введите ID сотрудника: ";
    cin >> ID;
 
}
Использую getline(), чтобы можно было ставить пробелы при вводе имени.

Далее в функции main() я делаю следующее:

C++
1
2
3
4
5
6
7
8
9
do {
 
    cout << endl << "Введите данные о работнике с номером " << i + 1 << endl;
    staff[i++].setData();
 
    cout << "Продолжить ввод данных? (y/n): ";
    cin >> answer;
 
} while (answer != 'n');
При этом из-за ввода ответа пользователем о продолжении работы, следующий ввод имени сотрудника работает некорректно (скриншот). Как исправить?
Миниатюры
Очистка потока  
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.08.2016, 11:35
Ответы с готовыми решениями:

Очистка потока
Так получается в программе, что приходится несколько раз открывать файл и закрывать, в ходе этого...

Очистка потока ввода
Собственно тема подымалась в интернете, но внятного объяснения я не получил. Для ввода строки с...

Очистка буфера потока
И снова здравствуйте, возникла снова проблема теперь уже иного рода. Есть код который заносит в...

Очистка потока _getch()
Сетевая прога. getch() считывает клавишу пользователя, делает действие и переключается в состояние...

19
Модератор
Эксперт CЭксперт С++
5284 / 2371 / 342
Регистрация: 20.02.2013
Сообщений: 5,770
Записей в блоге: 20
21.08.2016, 11:40 2
Лучший ответ Сообщение было отмечено Nishen как решение

Решение

Nishen, тынц.
1
1352 / 851 / 365
Регистрация: 26.02.2015
Сообщений: 3,799
21.08.2016, 11:56  [ТС] 3
gru74ik, спасибо большое!

Добавлено через 5 минут
А почему мне не помогает вариант с cin.sync()?

Пытаюсь сделать вот так:

C++
1
2
3
4
5
6
7
8
9
10
do {
 
    cout << endl << "Введите данные о работнике с номером " << i + 1 << endl;
    staff[i++].setData();
 
    cout << "Продолжить ввод данных? (y/n): ";
    cin >> answer;
    cin.sync();
        
} while (answer != 'n');
0
Модератор
Эксперт CЭксперт С++
5284 / 2371 / 342
Регистрация: 20.02.2013
Сообщений: 5,770
Записей в блоге: 20
21.08.2016, 11:59 4
Nishen, весь свой код скинь.
0
1352 / 851 / 365
Регистрация: 26.02.2015
Сообщений: 3,799
21.08.2016, 12:03  [ТС] 5
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//CHAPTER 7 - JOB_02
//main.cpp
 
#include <iostream>
#include <string>
 
using namespace std;
 
 
class Employee {
 
    private:
        string name;
        long ID;
 
    public:
        Employee();
        Employee(string n, long id);
        void setData();
        void setData(string n, long id);
        void setData(char n[], long id);
        void getData() const;
 
};
//-----------------------------------------------------------------------------
Employee::Employee() : name(""), ID(0) {
 
}
//-----------------------------------------------------------------------------
Employee::Employee(string n, long id) : name(n), ID(id) {
 
}
//-----------------------------------------------------------------------------
void Employee::setData() {
    
    cout << "Введите имя: ";
    getline(cin, name);
    
    cout << "Введите ID сотрудника: ";
    cin >> ID;
 
}
//-----------------------------------------------------------------------------
void Employee::setData(string n, long id) {
 
    name = n;
    ID = id;
 
}
//-----------------------------------------------------------------------------
void Employee::setData(char n[], long id) {
 
    int length = strlen(n);
 
    for (int i = 0; i < length; i++) {
 
        name[i] = n[i];
 
    }
 
    ID = id;
}
//-----------------------------------------------------------------------------
void Employee::getData() const {
 
    cout << "Сотрудник №" << ID << ". Имя: " << name;
 
}
 
 
 
int main() {
 
    setlocale(LC_ALL, "Russian");
 
    const int MAX = 100;
 
    Employee staff[MAX];
 
    int i = 0;
    char answer = 'y';
 
    do {
 
        cout << endl << "Введите данные о работнике с номером " << i + 1 << endl;
        staff[i++].setData();
 
        cout << "Продолжить ввод данных? (y/n): ";
        cin >> answer;
        cin.sync();
        
 
    } while (answer != 'n');
 
    for (int j = 0; j < i; j++) {
 
        staff[j].getData();
        cout << endl;
 
    }
 
    system("PAUSE");
    return 0;
 
}
0
Модератор
Эксперт CЭксперт С++
5284 / 2371 / 342
Регистрация: 20.02.2013
Сообщений: 5,770
Записей в блоге: 20
21.08.2016, 12:13 6
Странно. У меня все работает нормально. Правда, я два заголовочника добавил:
C++
1
2
#include <cstdlib> // для system()
#include <cstring> // для strlen()
Миниатюры
Очистка потока  
0
1352 / 851 / 365
Регистрация: 26.02.2015
Сообщений: 3,799
21.08.2016, 12:16  [ТС] 7
gru74ik, а у Вас в цикле do-while используется функция sync()? Просто я сначала не тот вариант скопировал из IDE, потом исправил.
0
Модератор
Эксперт CЭксперт С++
5284 / 2371 / 342
Регистрация: 20.02.2013
Сообщений: 5,770
Записей в блоге: 20
21.08.2016, 12:25 8
Nishen, у меня так:
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//CHAPTER 7 - JOB_02
//main.cpp
 
#include <iostream>
#include <string>
#include <cstdlib> // для system()
#include <cstring> // для strlen()
 
using namespace std;
 
 
class Employee {
 
    private:
        string name;
        long ID;
 
    public:
        Employee();
        Employee(string n, long id);
        void setData();
        void setData(string n, long id);
        void setData(char n[], long id);
        void getData() const;
 
};
//-----------------------------------------------------------------------------
Employee::Employee() : name(""), ID(0) {
 
}
//-----------------------------------------------------------------------------
Employee::Employee(string n, long id) : name(n), ID(id) {
 
}
//-----------------------------------------------------------------------------
void Employee::setData() {
 
    cout << "Введите имя: ";
    getline(cin, name);
 
    cout << "Введите ID сотрудника: ";
    cin >> ID;
 
}
//-----------------------------------------------------------------------------
void Employee::setData(string n, long id) {
 
    name = n;
    ID = id;
 
}
//-----------------------------------------------------------------------------
void Employee::setData(char n[], long id) {
 
    int length = strlen(n);
 
    for (int i = 0; i < length; i++) {
 
        name[i] = n[i];
 
    }
 
    ID = id;
}
//-----------------------------------------------------------------------------
void Employee::getData() const {
 
    cout << "Сотрудник №" << ID << ". Имя: " << name;
 
}
 
 
 
int main() {
 
    setlocale(LC_ALL, "Russian");
 
    const int MAX = 100;
 
    Employee staff[MAX];
 
    int i = 0;
    char answer = 'y';
 
    do {
 
        cout << endl << "Введите данные о работнике с номером " << i + 1 << endl;
        staff[i++].setData();
        cout << "Продолжить ввод данных? (y/n): ";
        cin >> answer;
        cin.sync();
 
    } while (answer != 'n');
 
    for (int j = 0; j < i; j++) {
 
        staff[j].getData();
        cout << endl;
 
    }
 
    system("PAUSE");
    return 0;
 
}
Добавлено через 5 минут
Nishen, а вообще, почему бы sync() не запихнуть прямо в функцию-член setData()?
C++
1
2
3
4
5
6
7
8
void Employee::setData() {
    cin.sync();
    cout << "Введите имя: ";
    getline(cin, name);
 
    cout << "Введите ID сотрудника: ";
    cin >> ID;
}
Тогда Вам не придётся заморачиваться с этим в мэйне. Ведь это, по сути, нюансы реализации. Пользователю не должно быть дела до того, как там класс устроен внутри.
1
1352 / 851 / 365
Регистрация: 26.02.2015
Сообщений: 3,799
21.08.2016, 12:27  [ТС] 9
Цитата Сообщение от gru74ik Посмотреть сообщение
почему бы sync() не запихнуть прямо в функцию-член setData
Да, спасибо за замечание. Но просто я использовал его изначально в метода setData(), он там не работал, я попробовал в main использовать его и так там и оставил. Странно, данный вариант решения проблемы на работает.
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
23.08.2016, 07:23 10
Цитата Сообщение от Nishen Посмотреть сообщение
А почему мне не помогает вариант с cin.sync()?
ОС какая?
1
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
23.08.2016, 07:54 11
Цитата Сообщение от Nishen Посмотреть сообщение
Странно, данный вариант решения проблемы на работает.
Поведение sync зависит от реализации платформы. Он не обязан очищать поток.
ЕМНИП, в Windows с Visual Studio будет очищать, под Unix'ами не будет (во всех ли юниксах так ).
1
Модератор
Эксперт CЭксперт С++
5284 / 2371 / 342
Регистрация: 20.02.2013
Сообщений: 5,770
Записей в блоге: 20
23.08.2016, 08:53 12
Цитата Сообщение от HelicopterK52 Посмотреть сообщение
в Windows с Visual Studio будет очищать
Code::Blocks 16.01 + MinGW 4.9.2 + Windows 7 - очищает.

Добавлено через 14 минут
QtCreator 3.3.0 + MinGW 4.9.1 + Windows 7 - очищает.
0
1352 / 851 / 365
Регистрация: 26.02.2015
Сообщений: 3,799
23.08.2016, 10:15  [ТС] 13
Цитата Сообщение от nd2 Посмотреть сообщение
ОС какая?
Windows 10 x64 Pro
Цитата Сообщение от HelicopterK52 Посмотреть сообщение
Windows с Visual Studio
Какая раз мой вариант, но не очищает.
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
23.08.2016, 11:00 14
Цитата Сообщение от Nishen Посмотреть сообщение
Какая раз мой вариант, но не очищает.
В Windows должно работать. Студия какая?

Добавлено через 31 минуту
Цитата Сообщение от Nishen Посмотреть сообщение
Windows 10 x64 Pro
Сейчас проверил, в 10-ке не работает. Вывод: не использовать, для таких целей, sync(). Другие есть способы:
https://cppstudy.wordpress.com... et-and-co/
1
1352 / 851 / 365
Регистрация: 26.02.2015
Сообщений: 3,799
23.08.2016, 11:02  [ТС] 15
Цитата Сообщение от nd2 Посмотреть сообщение
Студия какая?
2015
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.08.2016, 11:27 16
C++
1
2
3
4
5
6
void clear_input()
{
    std::wcin.clear(),
    std::wcin.ignore(std::numeric_limits<std::streamsize>::max(), L'\n');
    assert(std::wcin);
}
1
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
23.08.2016, 11:44 17
Цитата Сообщение от hoggy Посмотреть сообщение
std::wcin.ignore(std::numeric_limits<std::streamsize>::max(), L'\n');
Лучше так:
C++
1
std::wcin.ignore((std::numeric_limits<std::streamsize>::max)(), L'\n');
0
1352 / 851 / 365
Регистрация: 26.02.2015
Сообщений: 3,799
23.08.2016, 11:48  [ТС] 18
Цитата Сообщение от nd2 Посмотреть сообщение
Лучше так:
Чем Ваша конструкция отличается от конструкции hoggy? Я вижу пару скобок, но что это даёт?
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
23.08.2016, 11:51 19
Цитата Сообщение от Nishen Посмотреть сообщение
Я вижу пару скобок, но что это даёт?
Добавь в код #include <Windows.h> и посмотри, что будет без пары скобок.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.08.2016, 12:05 20
Цитата Сообщение от nd2 Посмотреть сообщение
Лучше так:
синтаксический мусор

Цитата Сообщение от nd2 Посмотреть сообщение
Добавь в код #include <Windows.h> и посмотри, что будет без пары скобок.
C++
1
2
#define _NOMINMAX
#include <windows.h>
0
23.08.2016, 12:05
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.08.2016, 12:05
Помогаю со студенческими работами здесь

Очистка потока ввода
ПОМОГИТЕ НАЙТИ ОШИБКУ Ребят написал малюсенький фрагмент кода, но уже есть ошибка. после того...

Телефонный справочник. Очистка потока ввода
Доброго времени суток!!! Нужно сделать подобие телефонного справочника! Вот мой код: # include...

Класс Person. Очистка потока ввода
Добрый вечер помогите найти ошибку в проге: задание : Разработайте класс Person, который...

Выполнение цикла. Очистка потока ввода
Добрый вечер. В данном коде тело цикла выполняется не n, а n-1 раз. Вернее, выполняется оно именно...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru