С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
 
[WRG]
51 / 51 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
#1

Очистка потока ввода && строки - C++

26.02.2013, 23:04. Просмотров 17213. Ответов 31
Метки нет (Все метки)

как вобще грамотно очистить поток после ввода множества всяких вещей с клавиатуры?
если совсем не чистить то остаются нажатия клавиши enter, если применять такой код
C++
1
2
3
cin.clear();
while(cin.get() != '\n');
cin.get();
в конце каждой функции в программе, где происходит ввод, то в итоге пользователю приходится 4-5 лишних раз давить enter после ввода чего либо, т.е. эффект обратный. как реализовать очистку потока вывода грамотно?

и еще, есть функция
C++
1
2
3
4
5
6
7
8
void initialize_values(goods *db)
{
    for (int i = 0; i < base_size; i++) {
        strcpy(db[i].value, '\0');
        db[i].cost = 0;
        db[i].quantity = 0;
    }
}
инициализирует массив записей при старте программы. в дальнейшем предполагается использовать db[i].value как критерий существования записи: если строка нулевая, то запись пустая и её можно заполнить. но у меня почему то не получается использовать if(!db[i].value) { ...........}, он просто не срабатывет. причем если value инициализировано как strcpy(db[i].value, '\0') ,то программа выдает просто segmentation vault и не работает, а если strcpy(db[i].value, "\0"), то компилируется без ошибок, но опять же if(!db[i].value) { ...........} не работает. в чем ошибка?
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.02.2013, 23:04
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Очистка потока ввода && строки (C++):

Ошибка: multiple definition of `void std::swap<A>(A&amp;, A&amp;) - C++
Хочу специализировать swap для своего класса. Получаю ошибку. Вот код:#ifndef A_H #define A_H #include &lt;string&gt; class A { ...

Цикл и строки, очистка потока ввода - C++
Возникла проблема. При вводе &quot;Y&quot; цикл переходит сразу к следующему вооду, то есть пропускает &quot;cin.getline&quot;. Как исправить? #include...

Почему friend ostrem& operator <<(ostream& outs, const Rational&); - invalid function declaration? - C++
Пытаюсь скомпилировать программу пишет friend ostrem&amp; operator &lt;&lt;(ostream&amp; outs, const Rational&amp;); - invalid function declaration. ...

В заштрихованную фигуру бросают точки с координатами x и y. Получить координаты первой точки не попавшей в эту область (фигура x*x+y*y<25&&x*x+y*y>=9& - C++
В заштрихованную фигуру бросают точки с координатами x и y. Получить координаты первой точки не попавшей в эту область (фигура...

ostream &operator<< (ostream &output, const Array &obj) - что означает эта строка? - C++
void Array::getArray() // вывод массива { for (int ix = 0; ix &lt; size; ix++) cout &lt;&lt; setw(5) &lt;&lt; ptr; // вывод элементов...

функции && строки - C++
ребята,пожалуйста,помогите.В понедельник практику сдавать,а эти задачи НЕМОГУ. 1. Написать процедуру для суммирования матриц. С ее...

31
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.02.2013, 23:26 #2
Цитата Сообщение от WRG Посмотреть сообщение
если применять такой код
C++
1
2
3
cin.clear();
while(cin.get() != '\n');
cin.get();
в конце каждой функции в программе, где происходит ввод, то в итоге пользователю приходится 4-5 лишних раз давить enter после ввода чего либо, т.е. эффект обратный. как реализовать очистку потока вывода грамотно?
Код для очистки вполне годится, только зачем в конце cin.get(); ? Поток уже чист. Лишнее ожидание ввода. Ещё способы: http://cppstudy.wordpress.com/2009/03/27/cin-get-and-co/
0
[WRG]
51 / 51 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
27.02.2013, 12:13  [ТС] #3
поток то может и чист, но в том месте где программа должна читать строку она это место пропускает, не дожидаясь ввода и нажатия enter. для этого и нужен cin.get() но все же тогда требуются лишние нажатия enter, не могу понять почему
0
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
27.02.2013, 18:11 #4
Ещё раз. После этой конструкции:
C++
1
2
cin.clear();
while(cin.get() != '\n');
в потоке никакого '\n' уже нет (извлекается последним перед выходом из while()). Поток чист и готов к работе. Дополнительное нажатие Enter будет требоваться как раз тогда, когда после этой конструкции поставить ещё и cin.get(). А если что-то где-то пропускается, то покажите код.
0
vua72
416 / 416 / 85
Регистрация: 28.11.2010
Сообщений: 1,183
Завершенные тесты: 1
27.02.2013, 18:15 #5
не мешайте разные методы ввода, или все cin, или cin.getline, или getline. Тогда проблем н будет.
0
xtorne21st
интересующийся
304 / 275 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
27.02.2013, 18:30 #6
C++
1
#define CIN_FLUSH if (std::cin.peek()) std::cin.ignore()
0
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
27.02.2013, 18:32 #7
Моё мнение, что дело не в этом. Мешать приходится, потому что эти методы для разного. Если бы они были полностью взаимозаменяемы, тогда да. Через getline() и cin.getline() не считать число или одиночный символ, через cin.getline() не считать объект string(или требуются дополнительные преобразования). Они специально сделаны разными, чтобы удобнее было использовать в разных случаях. Прсто нужно знать особенности каждого метода.
0
[WRG]
51 / 51 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
27.02.2013, 21:54  [ТС] #8
вот код, очистку оформил в виде функции, чтобы использовать после каждого ввода
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
 
const int base_size = 100; //максимальный размер базы данных
 
struct goods {
    char value[30];
    float cost;
    unsigned int quantity;
};
 
char show_menu(); //готово вроде как
void initialize_values(goods *db);  //готово вроде как
int find_end_of_db(goods *db);  //должно возврашать -1 если база заполнена, вроде готово
void add_item(goods *db, int position);
void delete_item(goods *db, int position);
void show_item(goods *db, int position);
void flush_stdin();
 
 
//******************MAIN*******************
int main(int argc, char *argv[])
{
    goods base[base_size];
    char user_choice;
    
    initialize_values(base);
    
    do {
        user_choice = show_menu();
        switch(user_choice) {
            case 'a': {
                int *end = new int (find_end_of_db(base));
                if (*end == -1) {
                    cout << "База заполнена! Удалите ненужные записи" << endl;
                    //if(system("cls")) system ("clear");
                    continue;
                }
                add_item(base, *end);
                delete end;
                break;
            }
            case 'd': {
                int *choice = new int;
                do {
                    cout << "Введите номер удаляемой записи -> " << endl;
                    cin >> *choice;
                    if ((*choice < 0) || (*choice > base_size)) {
                        cout << "Недопустимое значение! Введите заново" << endl;    
                    }
                } while ((*choice < 0) || (*choice > base_size));
                delete_item(base, *choice);
                delete choice; 
                break;
            }
            case 's': {
                char *s = new char;
                char *pch = 0;
                bool found = false;
                cout << "Введите навание товара -> ";
                gets(s);
                for (int i = 0; i < base_size; i++) {
                    pch = strstr(base[i].value, s); 
                    if (pch) {
                        show_item(base, i);
                        found = true;
                    };
                }
                if (!found) cout << "Ни одной записи с таким именем не найдено!" << endl;
                break;
            }
        }
        
        flush_stdin();
    } while (user_choice != 'q');
    
    
    return 0;
}
 
//****************SHOW MENU****************
char show_menu()
{
    char choice;
    bool stop = false;
    
    do {
        cout << "Выберите нужный пункт меню" << endl;
        cout << "a - добавить запись в базу" << endl;
        cout << "d - удалить запись из базы" << endl;
        cout << "s - показать запись из базы" << endl;
        cout << "q - выход из программы" << endl;
        cout << "-> ";
        cin >> choice;
        if ((choice =='a') || (choice =='d') || (choice =='s') || (choice == 'q')) stop = true;
        else cout << "Ошибка ввода. Повторите ввод" << endl;
    } while (!stop);
    
    flush_stdin();
    
    return choice;
}
 
//******************INITIALIZE VALUES**********
void initialize_values(goods *db)
{
    for (int i = 0; i < base_size; i++) {
        strcpy(db[i].value, "\0");
        //db[i].value = '\0';
        db[i].cost = 0;
        db[i].quantity = 0;
    }
}
 
//*****************FIND END OF DB*****************
int find_end_of_db(goods *db)
{
    int i;
    for (i = 0; i < base_size; i++) {
        if (!db[i].cost) break;
    }
    if (i == base_size) return -1;
    return i;
}
 
//******************ADD ITEM******************
void add_item(goods *db, int position)
{
    cout << "Ввод записи №" << position << endl;
    cout << "Введите название товара: ";
    gets(db[position].value);
    cout << endl;
    cout << "Введите стоимость товара: ";
    cin >> db[position].cost;
    cout << endl;
    cout << "Введите количество товара на складе: ";
    cin >> db[position].quantity;
    cout << endl;
    
    flush_stdin();
}
 
 
//*****************DELETE ITEM*************
void delete_item(goods *db, int position)
{
    cout << "Удаление записи №" << position << endl;
    strstr(db[position].value, "\0");
    db[position] .cost = 0;
    db[position].quantity = 0;
    cout << "Запись №"<< position << "успешно удалена!" << endl;
    
    flush_stdin();
}
 
//*******************SHOW ITEMS**************
void show_item(goods *db, int position)
{
    cout << "Вывод записи №" << position << endl;
    cout << "Название товара: " << db[position].value << endl;
    cout << "Стоимость товара: " << db[position].cost << endl;
    cout << "Количество товара на складе: " << db[position].quantity << endl;
    cout << endl;
    
    flush_stdin();
}
 
void flush_stdin()
{
    cin.clear();
    while(cin.get() != '\n');
}
1
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
27.02.2013, 22:25 #9
И где лишний раз Enter приходится нажимать?
0
[WRG]
51 / 51 / 9
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
27.02.2013, 23:13  [ТС] #10
да хоть где, например ввел запись, вывел ее на экран, и он ждет нескольких нажатий enter, или после всего этого если нажать q в меню то тоже несколько раз придется enter давить чтобы завершилась программа наконец
0
xtorne21st
интересующийся
304 / 275 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
27.02.2013, 23:32 #11
Цитата Сообщение от WRG Посмотреть сообщение
C++
1
while(cin.get() != '\n');
поробуйте вместо этого цикла воспользоваться макросом, который я описал выше
0
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
27.02.2013, 23:46 #12
Просто вы навставляли очистку потока где надо и где не надо. Нужно только после cin >> перед gets(), getline() и т.п. В частности, уберите flush_stdin(); в 77 строке и из тех функций, где нет ввода через cin >>.

Добавлено через 4 минуты
А вот что лучше не делать, так это использовать одновременно и функции ввода-вывода С и потоки С++. Лучше, наверное, что-то одно.
0
vua72
416 / 416 / 85
Регистрация: 28.11.2010
Сообщений: 1,183
Завершенные тесты: 1
28.02.2013, 00:13 #13
Прата так делает (пример 17.15, 2011 г.):
C++
1
inline void eatline() { while (std::cin.get() != '\n') continue; }
0
gray_fox
What a waste!
1522 / 1227 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 3
28.02.2013, 00:17 #14
C++
1
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
1
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.02.2013, 00:59 #15
Цитата Сообщение от vua72 Посмотреть сообщение
Прата так делает (пример 17.15, 2011 г.):
C++
1
inline void eatline() { while (std::cin.get() != '\n') continue; }
Не понимаю только, что это continue даёт?
0
28.02.2013, 00:59
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.02.2013, 00:59
Привет! Вот еще темы с ответами:

Порядок вычисления: операторы «|» и «||», «&» и «&&» - C++
В Java булевые операторы «|» и «||», и «&amp;» и «&amp;&amp;» отличаются друг от друга порядком вычеслений, а в C++ так же как и в Java или...

Friend ostream& operator<<(ostream& stream, CArr& obj); - C++
CArr.h #pragma once class CArr{ int* arr = nullptr; int size = 10; void swap(int *a, int *b); void swap(int &amp;a, int &amp;b); ...

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

Очистка потока ввода - C++
Собственно тема подымалась в интернете, но внятного объяснения я не получил. Для ввода строки с пробелами использую cin.getline() Если...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

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