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

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 70, средняя оценка - 4.96
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
#1

Не очищается поток после cin.clear() - C++

11.07.2011, 07:55. Просмотров 9240. Ответов 4
Метки нет (Все метки)

Собственно есть программа записывающая данные в файл и считывающая их оттудова со всеми сопутствующими функциями (новая запись, обновление записей между файлами, печать). Проблема в том что в функции по добавлении записи

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
void newRecord (fstream& file)
{
    int ID; // номер
    string Name;string SName; //имя и фамилия
    double balance; //баланс
 
    try
    {
        cout<<"\nEnter information about client\n(ID, Name, Second Name, balance):\n? ";
        cin>>ID>>Name>>SName>>balance;
 
        if (!cin.good())
         throw exception();
 
        file<<ID<<' '<<Name<<' '<<SName<<' '<<balance<<endl;
 
    }
 
    catch(exception)
    {
        cerr<<"\nError, wrong information";
        cin.clear();
        return;
    }
 
    return;
}
Если пойти по пути выброшенного исключения то программа напишет что есть ошибка и вернётся в главное меню, но при этом вводить ничего больше не получиться, хотя курсор будет мигать. Почему так? На всякий случай вся программа:
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#include <iostream>
#include <iomanip>
#include <cstring>
#include <fstream>
using namespace std;
 
int menu();
void newRecord (fstream&);
void update(fstream&);
void print(fstream&);
 
int main()
{
    fstream trans("trans.dat",ios::in|ios::app);
    fstream oldmast;
    if(!trans)
     cerr<<"\nCritical Error! Can not open file \"trans.dat\"\n";
    int choice=menu();
    while(choice)
    {
        switch (choice)
        {
            case 1:
            newRecord(trans);
            break;
 
            case 2:
            update(trans);
            break;
 
            case 3:
            print(trans);
            break;
 
            case 4:
            oldmast.open("oldmast.dat",ios::in);
            if(!oldmast)
             cerr<<"\nCritical Error! Can not open file \"oldmast.dat\"\n";
            print(oldmast);
            break;
 
            default:
            cerr<<"\nSomething wrong...\n";
        }
        cout<<"\n\n\n";
        if (oldmast)
         oldmast.close();
        choice=menu();
    }
 
 
}
 
int menu()
{
    cout<<"\t\t\tMAIN MENU"<<endl
    <<"1 - new record in DB"<<endl
    <<"2 - update all records"<<endl
    <<"3 - print \"trans.dat\""<<endl
    <<"4 - print \"oldmast.dat\""<<endl
    <<"0 - exit"<<endl
    <<"Enter your choice:\n? ";
    int choice;
    do
     cin>>choice;
    while(choice<0 || choice>4);
 
    return choice;
}
 
void newRecord (fstream& file)
{
    int ID; // номер
    string Name;string SName; //имя и фамилия
    double balance; //баланс
 
    try
    {
        cout<<"\nEnter information about client\n(ID, Name, Second Name, balance):\n? ";
        cin>>ID>>Name>>SName>>balance;
 
        if (!cin.good())
         throw exception();
 
        file<<ID<<' '<<Name<<' '<<SName<<' '<<balance<<endl;
 
    }
 
    catch(exception)
    {
        cerr<<"\nError, wrong information";
        cin.clear();
        return;
    }
 
    return;
}
 
void update(fstream& file)
{
    fstream oldmast("oldmast.dat",ios::out|ios::in);
    ofstream newmast("newmast.dat",ios::out);
    if(!newmast)
     perror("newmast.dat");
    if(!oldmast)
     perror("oldmast.dat");
 
    //установить курсор в начала файлов
    file.seekp(0);
    oldmast.seekp(0);
    newmast.seekp(0);
 
    int ID1,ID2;
    string Name1,Name2;
    string SName1,SName2;
    double balance1,balance2;
    oldmast>>ID1>>Name1>>SName1>>balance1;
 
    //пока есть записи в oldmast которые нужно перенести в newmast
    while(!oldmast.eof())
    {
        //ищем совпадения по ID в нашем файле
        file>>ID2>>Name2>>SName2>>balance2;
        while(!file.eof())
        {
            //если совпадение есть то изменить баланс считанный с oldmast
            if (ID1==ID2)
             balance1+=balance2;
 
            file>>ID2>>Name2>>SName2>>balance2;
        }
        file.clear(); //убрать метку конца файла для возможности последующего считывания
        file.seekp(0); //установить курсор в начало файла
        newmast<<ID1<<' '<<Name1<<' '<<SName1<<' '<<balance1<<endl; //записать данные в newmast
        oldmast>>ID1>>Name1>>SName1>>balance1; // считать новые данные из oldmast
    }
 
    oldmast.clear(); //убрать метку конца файла у oldmast
    file.clear(); //убрать метку конца файла у файла
    file.seekp(0); //установить курсор в начало файла
    oldmast.seekp(0); //установить курсор в начало oldmast.dat
 
 
    // проверить какие записи есть в файле и нет в oldmast
    // и выдать для них предупреждения так как они не будут перенесены
    // в основной файл
    file>>ID2>>Name2>>SName2>>balance2;
    while(!file.eof())
    {
        int flag=0;
 
        oldmast>>ID1>>Name1>>SName1>>balance1;
        while(!oldmast.eof())
        {
            //если номера совпадают то они были перенесены в файл newmast
            if (ID1==ID2)
            {
 
                flag=1;
                break;
            }
 
            oldmast>>ID1>>Name1>>SName1>>balance1;
        }
        oldmast.clear();//убрать метку конца файла у oldmast
        oldmast.seekp(0); //установить курсор на начало файла
 
        // если в oldmast нет записей с таким номером то выдать предупреждение
        if (flag==0)
         cerr<<"\nUnmatched transaction record for account number "<<ID2<<endl;
        file>>ID2>>Name2>>SName2>>balance2;
    }
 
    file.clear();
    //закрыть файлы
    oldmast.close();
    newmast.close();
 
    //удалить oldmast.dat
    if(remove("oldmast.dat"))
     perror("oldmast.dat");
 
    //переименовать newmast.dat в oldmast.dat для последующих операций обновления файлов
    if(rename("newmast.dat","oldmast.dat"))
     perror("newmast.dat");
}
 
void print(fstream& file)
{
    cout<<"\n\n";
    file.seekp(0,ios::end); //перевести курсор в конец файла
    //если при этом курсор будет в начале файла значит файл пуст
    if (!file.tellp())
    {
        cerr<<"\nFile is empty\n\n";
        return;
    }
 
    //иначе установить курсор в начало файла
    file.seekp(0);
    file.clear();
    int ID;
    string Name,SName;
    double balance;
 
    //считать первую строку данных
    file>>ID>>Name>>SName>>balance;
 
    //вывести подписи к данным
    cout<<setw(5)<<left<<"ID"<<setw(7)<<left<<"NAME"
    <<setw(10)<<left<<"Second Name"<<setw(8)<<right<<"BALANCE"<<endl;
 
    //пока есть записи которые можно вывести напечатать их
    while (!file.eof() && file.good())
    {
        cout<<setw(5)<<left<<ID<<setw(7)<<left<<Name
        <<setw(10)<<left<<SName<<setw(8)<<right<<balance<<endl;
 
        file>>ID>>Name>>SName>>balance;
    }
    file.clear();
}
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.07.2011, 07:55     Не очищается поток после cin.clear()
Посмотрите здесь:

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

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

Cin.clear cin.ignore - C++
Как использовать cin.clear и cin.ignore?

Cin.clear() не работает? - C++
Почему cin.clear() не работает как надо? ( не очищает поток ). Если мы вводим например 3 значения (123) то цикл срабатывает 3 раза. while...

cin.get() и cin.clear() - C++
В общем, занимаюсь по видео-урокам на ютубе, дошли до темы &quot;массивы&quot;. Суть программы - вывести наибольший и наименьший элемент (его...

Сброс состояния буфера cin.clear - C++
Всем привет. Пытаюсь контролировать ввод пользователя. Вопрос в следующем: почему очерёдность операций принципиальна : #include...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kastaneda
Форумчанин
Эксперт С++
4514 / 2856 / 228
Регистрация: 12.12.2009
Сообщений: 7,249
Записей в блоге: 1
Завершенные тесты: 1
11.07.2011, 10:36     Не очищается поток после cin.clear() #2
Попробуй после cin.clear(); добавить cin.sync();
easybudda
Эксперт CЭксперт С++
9465 / 5478 / 927
Регистрация: 25.07.2009
Сообщений: 10,502
11.07.2011, 10:48     Не очищается поток после cin.clear() #3
Цитата Сообщение от Gepar Посмотреть сообщение
C++
1
2
if(!trans) 
  cerr<<"\nCritical Error! Can not open file \"trans.dat\"\n";
Ну сказали пользователю, что есть проблема с открытием файла, и хватит с него, продолжаем выполнять программу... Может всё-таки на этом месте её и завершить, пока пользователь с файлами не разберётся?

Цитата Сообщение от Gepar Посмотреть сообщение
oldmast.open("oldmast.dat",ios::in);
Та же история...

Не факт, что на этом все ошибки кончатся, но так в любом случае не нужно делать...
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
11.07.2011, 12:13  [ТС]     Не очищается поток после cin.clear() #4
easybudda, да, и хватит с него, мне этого достаточно, а пишу это я для себя. Если честно то просто люблю более короткие записи, а когда добавляешь ещё и выход то надо скобки ещё доцеплять же {}, было бы в c++ что-то типа cerr<<... & exit() тогда хорошо Ну а так конечно же Вы правы, это плохая привычка.

Вообще могу прикрепить файлики с тестовыми данными ... нет, не надо, cin.sync() помогло, но как?

У меня изначально при неправильном вводе шла попытка записать символ в переменную int, если это случалось я прерывал выполнение новой записи и ничего не делал и всё возвращалось в main. Но собственно ведь попытка писать символ шла же, те: символ должен был убраться с потока и не застревать там, а он получается застревал ... хотя если бы он застревал то программа же должна была бы зациклиться в меню хотя бы (вывод менюшки-> ловля символа->опять вывод менюшки, такое у меня получалось часто в программах на с++ когда не верные данные вводишь), а оно получалось как-будто клавиатура отваливалась от входящего потока. Так что же происходило подскажите же? Может я до конца не понимаю что же делает cin.sync(). Тут более важно понять чего так, а не радоваться что заработало

Добавлено через 1 минуту
Кстати одного cin.sync() без cin.clear() у меня в программе не достаточно, ровно как и второго без первого (ну это я методом тыка чтобы посмотреть что же делает эта cin.sync() )
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.07.2011, 13:18     Не очищается поток после cin.clear()
Еще ссылки по теме:

Не очищается поток ввода - C++
Ребят,у меня не очищается поток ввода,и не вводится фамилия студента(сразу перескакивает на группу студента),помогите пожалуйста ,спасибо...

Для чего в код вводится cin.ignore после того, как cin>> уже сработало? - C++
Доброго времени суток! Просматриваю простой код. Вводится строка типа string: фунты и дюймы Затем значения переводится в типы int и...

Почему не работает cin.clear() и как работает sync()? - C++
#include&lt;iostream&gt; #include&lt;cstring&gt; using namespace std; char*input(char*ch,int&amp;n){ cin.getline(ch,20); //cin.sync(); ...

Поток cin - C++
Ребят подскажите почему после того как в цикле для потока cin устанавливается по команде Ctrl+z бит eofbit я не могу юзать поток cin он у...

Поток ввода cin - C++
Привет. Я только начинаю учить C++, так что не смейтесь если проблема примитивная, но всё равно прошу помочь :) Учусь по книге...

Запись в поток cin >> - C++
Люди добрые подскажите где взять инфу по функциям для ввода/вывода и форматирования. Например, что бы это значило: cout &lt;&lt;...


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

Или воспользуйтесь поиском по форуму:
asics
Freelance
Эксперт С++
2846 / 1783 / 144
Регистрация: 09.09.2010
Сообщений: 3,841
11.07.2011, 13:18     Не очищается поток после cin.clear() #5
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Gepar, cin.clear() - сброс битов ошибок входного стандартного потока
cin.sync() - очищение буфера стандартного ввода
Yandex
Объявления
11.07.2011, 13:18     Не очищается поток после cin.clear()
Ответ Создать тему
Опции темы

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