Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.54/225: Рейтинг темы: голосов - 225, средняя оценка - 4.54
52 / 52 / 37
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
1

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

26.02.2013, 23:04. Показов 44972. Ответов 32
Метки нет (Все метки)

как вобще грамотно очистить поток после ввода множества всяких вещей с клавиатуры?
если совсем не чистить то остаются нажатия клавиши 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

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.02.2013, 23:04
Ответы с готовыми решениями:

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

Цикл и строки, очистка потока ввода
Возникла проблема. При вводе &quot;Y&quot; цикл переходит сразу к следующему вооду, то есть пропускает...

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

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

32
5480 / 4875 / 831
Регистрация: 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/... et-and-co/
1
52 / 52 / 37
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
27.02.2013, 12:13  [ТС] 3
поток то может и чист, но в том месте где программа должна читать строку она это место пропускает, не дожидаясь ввода и нажатия enter. для этого и нужен cin.get() но все же тогда требуются лишние нажатия enter, не могу понять почему
0
5480 / 4875 / 831
Регистрация: 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
419 / 418 / 167
Регистрация: 28.11.2010
Сообщений: 1,183
27.02.2013, 18:15 5
не мешайте разные методы ввода, или все cin, или cin.getline, или getline. Тогда проблем н будет.
0
интересующийся
309 / 280 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
27.02.2013, 18:30 6
C++
1
#define CIN_FLUSH if (std::cin.peek()) std::cin.ignore()
2
5480 / 4875 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
27.02.2013, 18:32 7
Моё мнение, что дело не в этом. Мешать приходится, потому что эти методы для разного. Если бы они были полностью взаимозаменяемы, тогда да. Через getline() и cin.getline() не считать число или одиночный символ, через cin.getline() не считать объект string(или требуются дополнительные преобразования). Они специально сделаны разными, чтобы удобнее было использовать в разных случаях. Прсто нужно знать особенности каждого метода.
0
52 / 52 / 37
Регистрация: 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
5480 / 4875 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
27.02.2013, 22:25 9
И где лишний раз Enter приходится нажимать?
0
52 / 52 / 37
Регистрация: 20.11.2011
Сообщений: 243
Записей в блоге: 1
27.02.2013, 23:13  [ТС] 10
да хоть где, например ввел запись, вывел ее на экран, и он ждет нескольких нажатий enter, или после всего этого если нажать q в меню то тоже несколько раз придется enter давить чтобы завершилась программа наконец
0
интересующийся
309 / 280 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
27.02.2013, 23:32 11
Цитата Сообщение от WRG Посмотреть сообщение
C++
1
while(cin.get() != '\n');
поробуйте вместо этого цикла воспользоваться макросом, который я описал выше
0
5480 / 4875 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
27.02.2013, 23:46 12
Просто вы навставляли очистку потока где надо и где не надо. Нужно только после cin >> перед gets(), getline() и т.п. В частности, уберите flush_stdin(); в 77 строке и из тех функций, где нет ввода через cin >>.

Добавлено через 4 минуты
А вот что лучше не делать, так это использовать одновременно и функции ввода-вывода С и потоки С++. Лучше, наверное, что-то одно.
0
419 / 418 / 167
Регистрация: 28.11.2010
Сообщений: 1,183
28.02.2013, 00:13 13
Прата так делает (пример 17.15, 2011 г.):
C++
1
inline void eatline() { while (std::cin.get() != '\n') continue; }
0
What a waste!
1603 / 1297 / 178
Регистрация: 21.04.2012
Сообщений: 2,720
28.02.2013, 00:17 14
C++
1
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
2
5480 / 4875 / 831
Регистрация: 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
1174 / 887 / 94
Регистрация: 03.08.2011
Сообщений: 2,457
28.02.2013, 01:24 16
http://www.daniweb.com/softwar... put-stream
В частности код:

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
#include <ios>
#include <istream>
#include <limits>
template <typename CharT>
std::streamsize ignore_line (
  std::basic_istream<CharT>& in, bool always_discard = false )
{
  std::streamsize nread = 0;
  if ( always_discard
    || ( in.rdbuf()->sungetc() != std::char_traits<CharT>::eof()
    && in.get() != in.widen ( '\n' ) ) )
  {
    // The stream is good, and we haven't
    // read a full line yet, so clear it out
    in.ignore ( std::numeric_limits<std::streamsize>::max(), in.widen ( '\n' ) );
    nread = in.gcount();
  }
  return nread;
}
class ignoreline {
  bool _always_discard;
  mutable std::streamsize _nread;
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;
  }
};
 
int main()
{
  std::cout<<"First input: ";
  std::cin.get();
  std::cout<<"Clearing cin.\n";
  std::cin>> ignoreline();
  std::cout<<"All done.\n";
}
0
419 / 418 / 167
Регистрация: 28.11.2010
Сообщений: 1,183
28.02.2013, 01:31 17
Цитата Сообщение от alsav22 Посмотреть сообщение
Не понимаю только, что это continue даёт?
отбрасывает остаток строки, если строка была прочитана не полностью.
Там пример такой
Кликните здесь для просмотра всего текста
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
// truncate.cpp -- using get() to truncate input line, if necessary
#include <iostream>
const int SLEN = 10;
inline void eatline() { while (std::cin.get() != '\n') continue; }
int main()
{
    using std::cin;
    using std::cout;
    using std::endl;
 
    char name[SLEN];
    char title[SLEN];
    cout << "Enter your name: ";
    cin.get(name,SLEN);
    if (cin.peek() != '\n')
        cout << "Sorry, we only have enough room for "
                << name << endl;
    eatline();
    cout << "Dear " << name << ", enter your title: \n";
    cin.get(title,SLEN);
    if (cin.peek() != '\n')
        cout << "We were forced to truncate your title.\n";
    eatline();
    cout << " Name: " << name
         << "\nTitle: " << title << endl;
    // cin.get();
    return 0; 
}
0
1174 / 887 / 94
Регистрация: 03.08.2011
Сообщений: 2,457
28.02.2013, 01:36 18
vua72, этот continue там ни к чему, и написан, скорей всего, просто для читаемости.
0
What a waste!
1603 / 1297 / 178
Регистрация: 21.04.2012
Сообщений: 2,720
28.02.2013, 01:38 19
Цитата Сообщение от alsav22 Посмотреть сообщение
Не понимаю только, что это continue даёт?
Ничего. Возможно для ясности.
0
5480 / 4875 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
28.02.2013, 01:44 20
Цитата Сообщение от vua72 Посмотреть сообщение
отбрасывает остаток строки, если строка была прочитана не полностью.
Куда что там отбрасывать, если чтение по символу, пока не встретится '\n'? Что с continue, что без...
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.02.2013, 01:44

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

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

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

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


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

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

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