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

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

Войти
Регистрация
Восстановить пароль
 
Ohiko
0 / 0 / 0
Регистрация: 04.12.2013
Сообщений: 11
#1

Защита от дурака (пустое значение в названии) - C++

06.12.2013, 02:13. Просмотров 664. Ответов 14
Метки нет (Все метки)

Доброго вечера)
Я пытаюсь сделать защиту от дурака, если конкретно - проверку при на ввод названия пустого значение, т.е. пробела или энтера. Только вот с энтером проблема. Объясните, если не сложно в чем моя ошибка)
C++
1
2
3
4
5
6
7
8
do{flag=0;
        cout<<"Введите название книги: ";
        gets (b);
        if((b[0]==' ') flag=1;
        for(i=0;i<strlen(b); i++)
        {if(b[i]=='\n') flag=1;
        }
    strcpy(r.book, b);
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
el_gato_de_Ch
35 / 35 / 1
Регистрация: 28.04.2013
Сообщений: 110
06.12.2013, 06:29     Защита от дурака (пустое значение в названии) #2
ответ

читаем

function
gets char * gets ( char * str );

Get string from stdin
Reads characters from the standard input (stdin) and stores them as a C string into str until a newline character or the end-of-file is reached.

клавиши enter (newline character)у тебя ну никак не может встретится в названии...
Ohiko
0 / 0 / 0
Регистрация: 04.12.2013
Сообщений: 11
06.12.2013, 16:32  [ТС]     Защита от дурака (пустое значение в названии) #3
Тогда как сделать, что бы пустого значения при нажатии энтера не заносилось?)
el_gato_de_Ch
35 / 35 / 1
Регистрация: 28.04.2013
Сообщений: 110
06.12.2013, 16:35     Защита от дурака (пустое значение в названии) #4
кидани весь код, хотелось бы посмотреть на всё задание.
Ohiko
0 / 0 / 0
Регистрация: 04.12.2013
Сообщений: 11
06.12.2013, 17:01  [ТС]     Защита от дурака (пустое значение в названии) #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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
void oadd()
{system("cls");
char str[256],o, a[30], b[30]; int flag=1, flag1=1,m, p=1,n,i;
cout <<"Добавление записи в файл заказов."<<endl;
if ((fr=fopen("C:\\Rastsenki.dat","rb"))==NULL)
    {cout<<"Невозможно открыть файл заказов."<<endl;
    p=0;
    getch();
    fclose(fr);
    }
        else{if(fread(&r,sizeof(r),1,fr)==0)
                {p=0;
                cout<<endl<<"Файл расценок пуст.Добавление невозможно.";
                getch();
                fclose(fr);
                }
            if(p==1)
            {do
                    {fz=fopen("C:\\Zakazi.dat","a+b");
                    cout<<endl<<"Показать список доступных книг? (д/y)";
                    cin>>o;
                    if((o=='д')||(o=='y')||(o=='Y')||(o=='Д')) rprosm();
                    cout<<endl<<"‚Введите данные для заказа.";
                    
                //  do{flag=1;
                    cout<<endl<<"Фамилия заказчика*: ";
                    gets (str);
                    str[18]='\0';
                    //for(i=0;i<strlen(str); i++)
                    //{if((str[i]==' ')||(str[i]=='\n')) flag=0;}
                    strcpy(z.pibz, str);
                    //}while(flag);
                    cout<<"Название книги: ";
                    gets (b);
                    b[17]='\0';
                    strcpy(z.book, b);
                    cout<<"Автор: ";
                    gets (a);
                    a[18]='\0';
                    strcpy(z.piba, a);
                    fr=fopen("C:\\Rastsenki.dat","r+b");
                    rewind(fz);
                    rewind(fr);
                    while(!feof(fr))
                    {if ((strcmp(z.book,r.book)==0)&&(strcmp(z.piba,r.piba)==0))
                        {flag1=0;
                        }
                        fread(&r,sizeof(r),1,fr);
                    }
                    if(flag1){cout<<endl<<"Такой книги нет в файле расценок.";
                            getch();
                            }
                    else{ cout<<endl<<"Введите количество книг*по форматам:";
                            do
                            {system("cls");
                            flag=0;
                            cout<<endl<<"Кол-во книг формата М: ";
                            gets(a);
                            z.km=atoi(a);
                            if((z.km<0)||(z.km>999)){flag=1; cout<<endl<<"Данное число не подходит."; getch(); }
                            if(z.km>r.km){ flag=1; cout<<endl<<"Данное число превышает количество доступных для заказа книг."<<endl; getch(); }
                            n=strlen(a);
                            for(int y=0;y<n;y++)
                            if((!isdigit(a[y]))) if(a[y]!='-'){flag=1; cout<<"Повторите ввод!";  getch(); }
                            }while(flag);
                           do
                            {system("cls");
                            flag=0;
                            cout<<endl<<"Кол-во книг формата C: ";
                            gets(a);
                            z.ks=atoi(a);
                            if((z.ks<0)||(z.ks>999)){flag=1; cout<<endl<<"Данное число не подходит."<<endl;}
                            if(z.ks>r.ks){ flag=1; cout<<endl<<"Данное число превышает количество доступных для заказа книг."<<endl;}
                            n=strlen(a);
                            for(int y=0;y<n;y++)
                            if((!isdigit(a[y]))) if(a[y]!='-'){flag=1; cout<<"Повторите ввод!";}
                            }while(flag);
 
                            do
                            {system("cls");
                            flag=0;
                            cout<<endl<<"Кол-во книг формата Б: ";
                            gets(a);
                            z.kv=atoi(a);
                            if((z.kv<0)||(z.kv>999)){flag=1; cout<<endl<<"Данное число не подходит."<<endl;}
                            if(z.kv>r.kv){ flag=1; cout<<endl<<"Данное число превышает количество доступных для заказа книг."<<endl;}
                            n=strlen(a);
                            for(int y=0;y<n;y++)
                            if((!isdigit(a[y]))) if(a[y]!='-'){flag=1; cout<<"Повторите ввод!";}
                            }while(flag);
 
                         if((z.km==0)&&(z.ks==0)&&(z.kv==0))
                         cout<<endl<<"Вы не выбрали ни одной книги. Заказ отменен";
                         else
                        {
                        FILE *pr;
                        fclose(fr);
                        pr=fopen("C:\\Rastsenki.dat","r+b");
                        fread(&r,sizeof(r),1,pr);
                        while(!feof(pr))
                            {if ((strcmp(z.book,r.book)==0)&&(strcmp(z.piba,r.piba)==0))
                                {z.tsena=z.km*r.cm+z.ks*r.cs+z.kv*r.cv;
                                r.km=r.km-z.km;
                                r.ks=r.ks-z.ks;
                                r.kv=r.kv-z.kv;
                                int q=sizeof(r);
                                fseek(pr,-q,1);
                                fwrite(&r,sizeof(r),1,pr);
                                fseek(pr,q,q);
                                if(z.tsena>9999.99) {cout<<endl<<"Оформление заказа производится на суму не более 9999.99 Ја*."<<endl;}
                                }
                                fread(&r,sizeof(r),1,pr);
                            }
                        fwrite(&z,sizeof(z),1,fz);
                        fclose(pr);
                        cout<<endl<<"Запись добавлена.";
                        }
                        }
                    fclose(fz);
                    cout<<endl<<"Добавить еще одну запись?";
                    cin>>o;
                    }while ((o=='y')||(o=='Y')||(o=='¤')||(o=='„'));
            }
                fclose(fz);
            }
                
}
и описание структуры
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
struct Zakazi
{ char pibz[20];
  char book[20];
  char piba[20];
  int km, ks, kv;
  float tsena;
}z;
struct Rastsenki
{     char book[20];
      char piba[20];
      int km, ks, kv;
      float cm,cs,cv;
}r;
el_gato_de_Ch
35 / 35 / 1
Регистрация: 28.04.2013
Сообщений: 110
06.12.2013, 17:52     Защита от дурака (пустое значение в названии) #6
офигеть !!! чувак, как ты в этом разобрался ... через чур многа букаф ...

друже ... прежде чем дальше продолжать писать эту программу

1. называй переменные осмысленно имена, a, b, r,f, fz - не читаемо !!! вообще никогда больше так не делай, i,j,k,l - пользуй для счётчиков цикла, для всего остального должны быть нормальные имена!
2. разбей всё на маленькие функции, выделяй основные блоки, где проверка, где ввод значений, так будет проще разбираться, а программа станет более структурированной

пусть в меня закидают камнями, Но я бы это переписал ...
MrGluck
Ворчун
Эксперт CЭксперт С++
6409 / 3607 / 448
Регистрация: 29.11.2010
Сообщений: 9,532
06.12.2013, 17:59     Защита от дурака (пустое значение в названии) #7
el_gato_de_Ch, лови

Все верно сказано. А еще не стоит мешать С и С++ (для работы с файлами в С++ есть fstream). От абсолютных путей избавьтесь также. Читайте не блоками, а посимвольно. Пробелы расставляйте, читать невозможно.

А проверка эта, что в шапке темы озвучена, делается так:
C++
1
2
3
4
std::string text;
do
    std::cin >> text;
while (text.empty());
el_gato_de_Ch
35 / 35 / 1
Регистрация: 28.04.2013
Сообщений: 110
06.12.2013, 18:07     Защита от дурака (пустое значение в названии) #8
воу воу =) а разве он вообще запишет что-нибудь после gets если я просто нажму enter, прога будет ждать ввода хоть какого-либо символа или я что-то путаю ?
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
06.12.2013, 18:34     Защита от дурака (пустое значение в названии) #9
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    char b[45];
    char r[45];
    int flag;
    do
    {
        flag = 1;
        cout<<"Введите название книги: ";
        gets (b);
        if (strlen(b) == 0) flag = 1;
        for(int i = 0; i < strlen(b); i++)
        {
            if(b[i] != ' ') 
            {
                flag = 0;
                break;
            }
        }
        if (flag == 0) strcpy(r, b);
    } while (flag);
Zazy
39 / 39 / 11
Регистрация: 14.04.2013
Сообщений: 171
06.12.2013, 18:44     Защита от дурака (пустое значение в названии) #10
Если ничего не ввели "нажали энтер" то строка пустая тогда можно строку сравнить с "\0"
MrGluck
Ворчун
Эксперт CЭксперт С++
6409 / 3607 / 448
Регистрация: 29.11.2010
Сообщений: 9,532
06.12.2013, 18:58     Защита от дурака (пустое значение в названии) #11
el_gato_de_Ch, если вы про мой код, то там будет выполняться считывание до тех пор, пока строка будет пуста, т.е. все пробелы и нажатия Enter будут игнорироваться. Можете проверить результат работы с помощью вывода на экран строки после цикла.
Ohiko
0 / 0 / 0
Регистрация: 04.12.2013
Сообщений: 11
06.12.2013, 19:05  [ТС]     Защита от дурака (пустое значение в названии) #12
Ваши замечания я постараюсь учесть но сдается если я этим займусь, то курсак переделывать весь придется)
Цитата Сообщение от MrGluck Посмотреть сообщение

C++
1
2
3
4
std::string text;
do
    std::cin >> text;
while (text.empty());
этот пример что-то совсем не вписывается, ошибки выдает... ну или я глупая слишком)



Цитата Сообщение от alsav22 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    char b[45];
    char r[45];
    int flag;
    do
    {
        flag = 1;
        cout<<"Введите название книги: ";
        gets (b);
        if (strlen(b) == 0) flag = 1;
        for(int i = 0; i < strlen(b); i++)
        {
            if(b[i] != ' ') 
            {
                flag = 0;
                break;
            }
        }
        if (flag == 0) strcpy(r, b);
    } while (flag);
большое спасибо, это именно то что я пыталась сделать))
MrGluck
Ворчун
Эксперт CЭксперт С++
6409 / 3607 / 448
Регистрация: 29.11.2010
Сообщений: 9,532
06.12.2013, 19:13     Защита от дурака (пустое значение в названии) #13
Цитата Сообщение от Ohiko Посмотреть сообщение
что-то совсем не вписывается, ошибки выдает
так а где ошибки то? Почем мне знать куда вы это вставили и как? УМВР.

Вот вам примеры реализации схожих заданий:
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
#include <iostream>
#include <fstream>
#include <string>
#include <cstddef>
#include <clocale>
#include <conio.h>
#include <cstdlib>
 
using namespace std;
 
// <<<<<<<-------- описание структуры и методов для работы с ней -------->>>>>>>
struct NOTE
{
    string surname; // фамилия
    string name;    // имя
    string tel;     // номер телефона
    int date[3];    // дата рождения
    bool filled;    // заполнена ли структурная переменная
 
    // методы
    NOTE();             // конструктор по-умолчанию (для создания в массиве)
    NOTE(const string &, const string &, const string &, const int, const int,
        const int);     // аргументированный конструктор
    void print() const; // вывод на экран в удобном формате
    void init();        // используется для инициализации
};
 
// перегружаем оператор для сравнения при сортировке
bool operator< (const NOTE &, const NOTE &);
// перегружаем оператор считывания с потока
istream & operator>> (istream &, NOTE &);
 
// <<<<<<<<----------- описание функций для работы программы ----------->>>>>>>>
// функция сортировки массива записей
void mySort(NOTE *, const size_t);
 
// обработка меню
void menu(NOTE *, const size_t);
void menuChoise(NOTE *, const size_t, const int choise);
 
// выводы информации на экран
void printMenu();
void printAllNOTES(NOTE *, const size_t);
 
// управление записями
// добавление записи в первый свободный элемент массива
void addNOTE(NOTE *, const size_t);
// удаление записи по фамилии
void delBySurname(NOTE *, const size_t, const string &);
 
// поиск записей
// возвращает индекс первой свободной записи
size_t findFirstEmpty(const NOTE *, const size_t);
// поиск по фамилии
bool findBySurname(const NOTE *, const size_t, const string &);
 
// пустой ли массив (все записи свободны)
bool isEmpty(const NOTE *, const size_t);
 
// работа с файлами
void readFromFile(NOTE *, const size_t);
 
 
// <<<<<<<<<<<<<<<--------------- главная функция --------------->>>>>>>>>>>>>>>
int main()
{
    setlocale(LC_ALL, "");
    const size_t NOTE_SIZE = 8; // размер массива структур
    NOTE n[NOTE_SIZE];          // массив записей
    menu(n, NOTE_SIZE);         // входим в основной цикл программы
 
    return 0;
}
 
 
// <<<<<<-------- реализация структуры и методов для работы с ней -------->>>>>>
NOTE::NOTE() : surname(), name(), tel(), filled(false)
{}
 
// используем список инициализации
NOTE::NOTE(const string &s, const string &n, const string &t, const int d1,
    const int d2, const int d3) : surname(s), name(n), tel(t), filled(false)
{
    date[0] = d1;
    date[1] = d2;
    date[2] = d3;
}
 
void NOTE::init()
{
    system("cls"); // очистка экрана
    cout << "Введите фамилию: ";
    cin >> surname;
    cout << "Введите имя: ";
    cin >> name;
    cout << "Введите номер телефона: ";
    cin >> tel;
    cout << "Введите дату рождения (через пробел): ";
    cin >> date[0] >> date[1] >> date[2];
    cout << endl;
    filled = true;
}
 
void NOTE::print() const
{
    cout << "Фамилия:        "   << surname
         << "\nИмя:            " << name
         << "\nНомер телефона: " << tel
         << "\nДата рождения:  " << date[0] << ' ' << date[1] << ' ' << date[2]
         << endl << endl;
}
 
bool operator< (const NOTE &n1, const NOTE &n2)
{
    // сравниваем по первым трем цифрам телефона
    return n1.tel.substr(0, 3) < n2.tel.substr(0, 3);
}
 
istream & operator>> (istream &ist, NOTE &n)
{
    // последовательно считываем данные
    ist >> n.surname >> n.name >> n.tel >> n.date[0] >> n.date[1] >> n.date[2];
    n.filled = true; // запись заполнена
    return ist; // возвращаем поток
}
 
 
// <<<<<<<----------- реализация функций для работы программы ----------->>>>>>>
 
void mySort(NOTE *n, const size_t size)
{
    for (size_t i=0; i < size-1; i++)
        for (size_t j=size-1; j > i; j--)
            if (n[j] < n[i])
            {
                NOTE tmp = n[i];
                n[i] = n[j];
                n[j] = tmp;
            }
}
 
void menu(NOTE *n, const size_t size)
{
    char choise;
    do
    {
        printMenu();
        cin >> choise; // запоминаем выбор
        if (choise < '0' || choise > '5')
        {
            cout << "\nВыберите корректный пункт меню\a"; // гудок
            _getch();
        }
        else
            menuChoise(n, size, choise - '0');
    } while (choise != '0');
}
 
void menuChoise(NOTE *n, const size_t size, const int choise)
{
    switch(choise)
    {
        case 1 :
            readFromFile(n, size);
            break;
 
        case 2 :
            addNOTE(n, size);
            break;
 
        case 3 :
            printAllNOTES(n, size);
            break;
 
        case 4 :
        {
            string key;
            cout << "\nВведите фамилию: ";
            cin >> key;
            bool result = findBySurname(n, size, key);
            if (!result)
            {
                cout << "\nЗаписей не найдено";
                _getch();
            }
            break;
        }
 
        case 5 :
        {
            string key;
            cout << "\nВведите фамилию: ";
            cin >> key;
            delBySurname(n, size, key);
            break;
        }
 
        default : // просто на всякий случай
            break;
    }
} // end of menuChoise(NOTE *, const size_t, const int)
 
void printMenu()
{
    system("cls"); // очистка экрана
    cout << "Что желаете сделать:\n"
         << "1. Ввод данных из файла\n"
         << "2. Ввод данных с клавиатуры\n"
         << "3. Просмотр всех данных\n"
         << "4. Вывод данных по фамилии\n"
         << "5. Удаление данных по запросу\n"
         << "0. Выход\n"
         << "\nВаш выбор: ";
}
 
void printAllNOTES(NOTE *n, const size_t size)
{
    if (isEmpty(n, size))
    {
        cout << "\a\nСписок записей пуст. Для начала заполните его";
        _getch();
        return;
    }
 
    system("cls");   // очистка экрана
    mySort(n, size); // сортируем по номеру телефона
    for (size_t i=0; i < size; i++)
        if (n[i].filled)  // если запись заполнена
            n[i].print(); // выводим её на экран
 
    cout << "Назад";
    _getch(); // пауза чтобы увидеть результаты работы
}
 
void addNOTE(NOTE *n, const size_t size)
{
    size_t index = findFirstEmpty(n, size); // ищем первую свободную
    if (index == size) // если записи заполнены
    {
        cout << "\n\aВсе записи заполнены";
        return ;
    }
    else // иначе вызываем функцию инициализации для свободной записи
        n[index].init();
}
 
void delBySurname(NOTE *n, const size_t size, const string &key)
{
    if (isEmpty(n, size))
    {
        cout << "\a\nСписок записей пуст. Для начала заполните его";
        _getch();
        return;
    }
 
    int counter = 0;
    for (size_t i=0; i < size; i++)
        // если запись заполнена и её фамилия совпадает
        if (n[i].filled && n[i].surname == key)
        {
            n[i].filled = false; // помечаем её как свободную
            ++counter;           // увеличиваем счетчик удаленных записей
        }
 
    cout << "\nУдалено " << counter << " элементов";
    _getch();
}
 
size_t findFirstEmpty(const NOTE *n, const size_t size)
{
    size_t index; // если не найдено, то вернет size (условно - код ошибки)
    // пока запись занята - инкрементируем индекс свободной записи
    for (index = 0; n[index].filled && index < size; index++);
 
    return index;
}
 
bool findBySurname(const NOTE *n, const size_t size, const string &key)
{
    bool finded = false; // найдена ли хоть одна запись
    for (size_t i=0; i < size; i++)
        if (n[i].surname == key) // если совпадает по фамилии
        {
            if (!finded) // если в первый раз
            {
                system("cls");
                finded = true; // нашли запись
            }
            n[i].print();  // выводим на экран
        }
 
    if (finded)   // если есть результат
    {
        cout << "Назад";
        _getch(); // то делаем паузу чтобы посмотреть на него
    }
    return finded;
}
 
bool isEmpty(const NOTE *n, const size_t size)
{
    for (size_t i=0; i < size; i++)
        if(n[i].filled) // если запись занята
            return false;   // возвращаем ложь
 
    return true; // пробежались по всем записям и ни одна не занята
}
 
// работа с файлами
void readFromFile(NOTE *n, const size_t size)
{
    ifstream ifs("NOTES.txt");
    if (!ifs)
    {
        cerr << "\a\nНевозможно найти файл";
        _getch();
        return;
    }
 
    size_t index, counter = 0;
    // пока не конец файла и есть свободное место в массиве записей
    while (!ifs.eof() && (index = findFirstEmpty(n, size)) != size)
    {
        ifs >> n[index]; // считываем данные в свободный элемент массива
        ++counter;       // увеличиваем счетчик считанных переменных на один
    }
 
    cout << "\nСчитано " << counter << " элементов";
    _getch();
    ifs.close(); // закрываем поток считывания с файла
}
Второй вариант:
Program.h
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
#ifndef _PROGRAM_H_
#define _PROGRAM_H_
#include <string>
#include <vector>
#include "Array.h"
#include "Film.h"
#define MAX_FILMS 100
 
typedef Array<Film> arr_Film;
typedef Array<Film>::iterator arr_Film_it;
typedef Array<Film>::const_iterator arr_Film_cit;
 
typedef std::vector<std::string> vec_str;
typedef std::vector<std::string>::iterator vec_str_it;
typedef std::vector<std::string>::const_iterator vec_str_cit;
 
 
class Program
{
    public:
        Program();
 
        // обработка меню
        void menu();
        void menuChoise(int choise);
        void menuFind();
        void menuFindChoise(int choise);
 
        // выводы информации на экран
        void printMenu() const;
        void printMenuFind() const;
        void printFilms() const;
 
        // управление фильмами
        void addFilm();
        void delFilm();
 
        // поиск фильмов по категориям
        bool findByName(const std::string &);
        bool findByGenre(const std::string &);
        bool findByYear(const int);
        bool findByCharacter(const std::string &);
 
        // работа с файлами
        void writeInFiles();
        void readFromFiles();
 
    private:
        arr_Film films; // список фильмов
        vec_str files;  // список файлов для считывания
        int counter;    // счетчик числа фильмов
};
 
#endif
Film.h
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
#ifndef _FILM_H
#define _FILM_H_
#include <string>
#include <vector>
 
typedef std::vector<std::string> vec_str;
typedef std::vector<std::string>::iterator vec_str_it;
typedef std::vector<std::string>::const_iterator vec_str_cit;
 
 
class Film
{
    public:
        // конструкторы
        Film();
        Film(const std::string &, const std::string &, const int, const int,
             const vec_str &);
 
        // set-методы
        void setName(const std::string &);
        void setGenre(const std::string &);
        void setMark(const int);
        void setYear(const int);
        void setCharacters(const vec_str &);
 
        // get-методы
        std::string getName() const;
        std::string getGenre() const;
        int getMark() const;
        int getYear() const;
        const vec_str& getCharacters() const;
 
        void print() const; // вывод информации на экран в удобном формате
 
    private:
        std::string name_;   // название
        std::string genre_;  // жанр
        int mark_;           // оценка
        int year_;           // год выпуска
        vec_str characters_; // основные герои
};
 
std::ostream & operator<< (std::ostream &, const Film &);
std::istream & operator>> (std::istream &, Film &);
 
#endif
Program.cpp
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
#include <iostream>
#include <fstream>
#include <clocale>
#include <conio.h>
#include <string>
#include <stdexcept>
#include "Program.h"
 
 
using namespace std;
 
Program::Program() : films(MAX_FILMS), files(), counter(0)
{
    setlocale(LC_ALL, "");
    ifstream ifs("files.txt");
    if (!ifs)
        throw runtime_error("File \"files.txt\" not found");
 
    string name;
    while (!ifs.eof() && ifs >> name)
        files.push_back(name);
}
 
void Program::menu()
{
    char choise;
    do
    {
        printMenu();
        cin >> choise; // запоминаем выбор
        if (choise < '0' || choise > '6')
        {
            cout << "\nВыберите корректный пункт меню\a"; // гудок
            _getch();
        }
        else
            menuChoise(choise - '0');
    } while (choise != '0');
}
 
void Program::menuChoise(int ch)
{
    switch(ch)
    {
        case 1 :
            printFilms();
            break;
 
        case 2 :
            addFilm();
            break;
 
        case 3 :
            delFilm();
            break;
 
        case 4 :
            menuFind();
            break;
 
        case 5 :
            writeInFiles();
            if (counter != 0)
            {
                cout << "\nЗаписано " << counter << " фильмов\n";
                _getch();
            }
            break;
 
        case 6 :
        {
            int last = counter;
            readFromFiles();
            cout << "\nСчитано " << counter - last << " фильмов\n";
            _getch();
            break;
        }
 
        default :
            break;
    }
} // end of Program::menuChoise(int ch)
 
void Program::menuFind()
{
    if (counter == 0)
    {
        cout << "\a\nСписок пуст, для начала заполните его\n";
        _getch();
        return;
    }
 
    char choise;
    do
    {
        printMenuFind();
        cin >> choise; // запоминаем выбор
        if (choise < '0' || choise > '4')
        {
            cout << "\nВыберите корректный пункт меню\a"; // гудок
            _getch();
        }
        else
            menuFindChoise(choise - '0');
    } while (choise < '0' || choise > '4');
}
 
void Program::menuFindChoise(int ch)
{
    switch(ch)
    {
        case 1 :
        {
            string name;
            cout << "Введите название: ";
            cin.ignore();
            getline(cin, name);
            bool result = findByName(name);
            if (!result)
                cout << "Фильмов по запросу не найдено\n";
            else
                cout << "Назад\n";
            _getch();
            break;
        }
 
        case 2 :
        {
            string genre;
            cout << "Введите жанр: ";
            cin.ignore();
            getline(cin, genre);
            bool result = findByGenre(genre);
            if (!result)
                cout << "Фильмов по запросу не найдено\n";
            else
                cout << "Назад\n";
            _getch();
            break;
        }
 
        case 3 :
        {
            int year;
            cout << "Введите год выпуска: ";
            cin >> year;
            bool result = findByYear(year);
            if (!result)
                cout << "Фильмов по запросу не найдено\n";
            else
                cout << "Назад\n";
            _getch();
            break;
        }
 
        case 4 :
        {
            string character;
            cout << "Введите актера: ";
            cin.ignore();
            getline(cin, character);
            bool result = findByCharacter(character);
            if (!result)
                cout << "Фильмов по запросу не найдено\n";
            else
                cout << "Назад\n";
            _getch();
            break;
        }
 
        default :
            break;
    }
} // end of Program::menuFindChoise(int choise)
 
void Program::printMenu() const
{
    system("cls"); // очистка экрана
    cout << "Что желаете сделать:\n"
         << "1. Вывести список всех фильмов\n"
         << "2. Добавить новый фильм\n"
         << "3. Удалить фильм\n"
         << "4. Меню поиска\n"
         << "5. Сохранить в файлы\n"
         << "6. Загрузить из файлов\n"
         << "0. Выход\n"
         << "\nВаш выбор: ";
}
 
void Program::printMenuFind() const
{
    system("cls"); // очистка экрана
    cout << "Вы находитесь в меню поиска фильмов\n"
         << "Что желаете сделать:\n"
         << "1. Искать по названию\n"
         << "2. Искать по жанру\n"
         << "3. Искать по году выпуска\n"
         << "4. Искать по герою\n"
         << "0. Выход\n"
         << "\nВаш выбор: ";
}
 
void Program::printFilms() const
{
    if (counter == 0)
    {
        cout << "\a\nСписок пуст, для начала заполните его\n";
        _getch();
        return;
    }
    system("cls");
    for (int i=0; i < counter; i++)
        films[i].print(); // для каждого элемента вызываем метод print
 
    cout << "\nНазад";
    _getch(); // пауза
}
 
void Program::addFilm()
{
    system("cls"); // очистка экрана
    cout << "Вы находитесь в меню добавления фильма\n"
         << "Если вы сюда вошли по ошибке, то введите \'exit\'\n";
    // временные переменные
    string name, genre, tmp;
    int mark, year;
    vec_str characters;
    cout << "Введите название фильма: ";
    cin.ignore();
    getline(cin, name);
    if (name == "exit") // если желаем выйти
        return;
    cout << "Введите жанр фильма: ";
    getline(cin, genre);
    do
    {
        cout << "Введите оценку фильма по 10-бальной школе: ";
        cin >> mark;
        if (mark < 0 || mark > 10)
            cout << "\aОшибка ввода. Введите число в диапазоне от 0 до 10\n";
    } while (mark < 0 || mark > 10);
    cout << "Введите год выпуска: ";
    cin >> year;
    cin.ignore(); // пропускаем символ '\n' оставшийся в потоке
 
    // пока считали строку и она не пустая
    cout << "Введите список основных киноактеров:\n"
         << "(Ввод заканчивается пустой строкой)\n";
    while(getline(cin, tmp) && !tmp.empty())
        characters.push_back(tmp); // добавляем в список героев
 
    // добавляем новый фильм в список
    films[counter++] = Film(name, genre, mark, year, characters);
} // end of Program::addFilm()
 
void Program::delFilm()
{
    if (counter == 0)
    {
        cout << "\a\nСписок пуст, для начала заполните его\n";
        _getch();
        return;
    }
    system("cls"); // очистка экрана
    cout << "Вы находитесь в меню добавления фильма\n"
         << "Если вы сюда вошли по ошибке, то введите \'exit\'\n";
    string name;
    cout << "Введите название фильма: ";
    cin.ignore();
    getline(cin, name);
    if (name == "exit") // если желаем выйти
        return;
 
    bool result = false; // нашли ли данный фильм
    for (int i=0; i < counter; i++)
        if (films[i].getName() == name)
        {
            // меняем местами с последним
            swap(films[counter-1], films[i]);
            counter--; // и уменьшаем счетчик
            result = true;
        }
    cout << (result ? "Фильм удален" : "Фильм не найден");
    _getch();
}
 
bool Program::findByName(const std::string& name)
{
    bool yes = false; // если нашли
    for (int i=0; i < counter; i++)
        if (films[i].getName() == name) // если совпадение по ключу
        {
            if (!yes) // если в первый раз
            {
                system("cls");
                cout << "Результат поиска:\n";
                yes = true;
            }
            films[i].print();
        }
    return yes;
}
 
bool Program::findByGenre(const std::string& genre)
{
    bool yes = false; // если нашли
    for (int i=0; i < counter; i++)
        if (films[i].getGenre() == genre) // если совпадение по ключу
        {
            if (!yes) // если в первый раз
            {
                system("cls");
                cout << "Результат поиска:\n";
                yes = true;
            }
            films[i].print();
        }
    return yes;
}
 
bool Program::findByYear(const int year)
{
    bool yes = false; // если нашли
    for (int i=0; i < counter; i++)
        if (films[i].getYear() == year) // если совпадение по ключу
        {
            if (!yes) // если в первый раз
            {
                system("cls");
                cout << "Результат поиска:\n";
                yes = true;
            }
            films[i].print();
        }
    return yes;
}
 
bool Program::findByCharacter(const std::string& character)
{
    bool yes = false; // если нашли
    for (int i=0; i < counter; i++)
    {
        // если поиск не дошел до конца, то будет истина
        bool result = find(films[i].getCharacters().begin(),
                           films[i].getCharacters().end(),
                           character) != films[i].getCharacters().end();
        if (result) // если совпадение
        {
            if (!yes) // если в первый раз
            {
                system("cls");
                cout << "Результат поиска:\n";
                yes = true;
            }
            films[i].print();
        }
    }
    return yes;
}
 
void Program::writeInFiles()
{
    if (counter == 0)
    {
        cout << "\a\nСписок пуст, для начала заполните его\n";
        _getch();
        return;
    }
 
    // создаем переменные для записи в определенные файлы
    ofstream out_comedies("comedies.txt"),
             out_dramas("dramas.txt"),
             out_horrors("horrors.txt"),
             out_thrillers("thrillers.txt"),
             out_fantastic("fantastic.txt"),
             out_other("other.txt");
 
    for (int i=0; i < counter; i++)
    {
        string genre = films[i].getGenre(); // узнаем жанр
        if (genre == "comedy")
            out_comedies << films[i];
        else if (genre == "drama")
            out_dramas << films[i];
        else if (genre == "horror")
            out_horrors << films[i];
        else if (genre == "thriller")
            out_thrillers << films[i];
        else if (genre == "fantastic")
            out_fantastic << films[i];
        else // если не подошел ни один из жанров
            out_other << films[i];
    }
 
    // обозначаем конец записей (дополнительная пустая строчка)
    out_comedies  << '\n';
    out_dramas    << '\n';
    out_horrors   << '\n';
    out_thrillers << '\n';
    out_fantastic << '\n';
    out_other     << '\n';
    // закрываем файлы
    out_comedies.close();
    out_dramas.close();
    out_horrors.close();
    out_thrillers.close();
    out_fantastic.close();
    out_other.close();
}
 
 
void Program::readFromFiles()
{
    for (vec_str_cit cit = files.begin(); cit != files.end(); ++cit)
    {
        ifstream ifs(cit->c_str());
        if (!ifs)
            cout << "File " << *cit << " not found\n";
 
        // считываем фильмы в контейнер, увеличивая счетчик при каждой итерации
        for (Film tmp; !ifs.eof() && ifs >> tmp; )
            if (counter < MAX_FILMS)
                films[counter++] = tmp;
        ifs.close();
    }
}
Film.cpp
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
#include <string>
#include <iostream>
#include "Film.h"
 
using namespace std;
 
Film::Film() : name_(), genre_(), mark_(), year_(), characters_()
{}
 
Film::Film(const string& name, const string& genre, const int mark,
    const int year, const vec_str& characters) : name_(name),
    genre_(genre), mark_(mark), year_(year), characters_(characters)
{}
 
void Film::setName(const string& name)
{
    name_ = name;
}
 
void Film::setGenre(const string& genre)
{
    genre_ = genre;
}
 
void Film::setMark(const int mark)
{
    mark_ = mark;
}
 
void Film::setYear(const int year)
{
    year_ = year;
}
 
void Film::setCharacters(const vec_str& characters)
{
    characters_ = characters;
}
 
string Film::getName() const
{
    return name_;
}
 
string Film::getGenre() const
{
    return genre_;
}
 
int Film::getMark() const
{
    return mark_;
}
 
int Film::getYear() const
{
    return year_;
}
 
const vec_str& Film::getCharacters() const
{
    return characters_;
}
 
void Film::print() const
{
    cout << "Название фильма:  "   << name_
         << "\nЖанр:             " << genre_
         << "\nОценка:           ";
    for (int i=0; i < mark_; i++)
        cout << '*';
    cout << " (" << mark_ << ")"
         << "\nГод выпуска:      " << year_
         << "\nВ главных ролях:  ";
    for (vec_str_cit cit = characters_.begin(); cit != characters_.end(); ++cit)
    {
        cout << *cit;
        if (cit + 1 != characters_.end())
            cout << ',';
        cout << ' ';
    }
    cout << endl << endl;
}
 
// перегружаем оператор вывода, функция принимает в качестве параметров ссылку
// на ostream и константную ссылку на объект класса Film
ostream & operator<< (ostream& out, const Film& f)
{
    out << f.getName() << '\n'
        << f.getGenre() << '\n'
        << f.getMark() << '\n'
        << f.getYear() << '\n';
    for (vec_str_cit cit = f.getCharacters().begin();
         cit != f.getCharacters().end(); ++cit)
        out << *cit << '\n';
    out << '\n';
    return out; // возвращаем сформированный поток
}
 
// перегружаем оператор ввода, функция принимает в качестве параметров ссылку
// на istream и ссылку на объект класса Film
istream & operator>> (istream& ist, Film& f)
{
    // временные переменные
    string name, genre, tmp;
    int mark, year;
    vec_str characters;
    // считываем в них
    getline(ist, name);
    getline(ist, genre);
    ist >> mark >> year;
    ist.ignore(); // пропускаем символ '\n' оставшийся в потоке
    // пока считали строку и она не пустая
    while(getline(ist, tmp) && !tmp.empty())
        characters.push_back(tmp); // добавляем в список героев
 
    // устанавливаем свойства
    f.setName(name);
    f.setGenre(genre);
    f.setMark(mark);
    f.setYear(year);
    f.setCharacters(characters);
    return ist; // возвращаем поток
}
main.cpp
C++
1
2
3
4
5
6
7
8
#include "Program.h"
 
int main()
{
    Program p;
    p.menu();
    return 0;
}
Там где Array - меняйте на обычный массив, Iterator - вообще забейте на него (там просто сама реализация несколько больше, я вам лишь часть файлов привел).
MrGluck
Ворчун
Эксперт CЭксперт С++
6409 / 3607 / 448
Регистрация: 29.11.2010
Сообщений: 9,532
06.12.2013, 19:16     Защита от дурака (пустое значение в названии) #14
Набор txt файлов для теста прикрепляю
files copy.rar
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.12.2013, 19:18     Защита от дурака (пустое значение в названии)
Еще ссылки по теме:

C++ "Защита от дурака" числа с плавающей запятой
C++ Защита от дурака
C++ защита от дурака как сделать?
C++ Защита от дурака
C++ Защита от дурака

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

Или воспользуйтесь поиском по форуму:
Ohiko
0 / 0 / 0
Регистрация: 04.12.2013
Сообщений: 11
06.12.2013, 19:18  [ТС]     Защита от дурака (пустое значение в названии) #15
То что я коряво вставила я признаю и так, не просить же исправлять вас) Сейчас еще почитаю,разберусь с этим. Спасибо за примеры.
Yandex
Объявления
06.12.2013, 19:18     Защита от дурака (пустое значение в названии)
Ответ Создать тему
Опции темы

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