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

Программа игнорирует gets() - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.89
Glam_Man
6 / 6 / 0
Регистрация: 15.10.2011
Сообщений: 73
23.12.2011, 12:16     Программа игнорирует gets() #1
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
#include <stdio.h>
#include <locale.h>
#include <string>
#include <iostream>
using namespace std;
struct NOTE
{
    char **family;
    char **name;
    int *phone;
    int **birthday;
};
void EditRecord(int count, NOTE &Note)
{
    char cccc, ccccc;
    system("cls");
    while(1)
    {
        printf("1.Редактирование фамилии %d записи\n", count);
        printf("2.Редактирование имени %d записи\n", count);
        printf("3.Редактирование номера телефона %d записи\n", count);
        printf("4.Редактирование даты рождения %d записи\n", count);
        printf("5.Возврат в меню выбора номера записи\n");
        scanf("%c", &cccc);
        system("cls");
        switch(cccc)
        {
            case '1':
                Note.family=new char*[count];
                for (int i=0; i<count; i++)
                {
                    Note.family[i]=new char[1];
                }
                printf("Введите фамилию %d записи\n", count);
                gets(Note.family[count-1]);
                printf("Фамилия успешно внесена в запись с номером %d\n", count);
                scanf("%c", &ccccc);
                scanf("%c", &ccccc);
                break;
            case '2':
                Note.name=new char*[count];
                for (int i=0; i<count; i++)
                {
                    Note.name[i]=new char[1];
                }
                printf("Введите имя %d записи\n\n", count);
                gets(Note.name[count-1]);
                printf("Имя успешно внесено в запись с номером %d\n", count);
                scanf("%c", &ccccc);
                scanf("%c", &ccccc);
                break;
            case '3':
                Note.phone=new int[100];
                printf("Введите номер телефона %d записи\n", count);
                scanf("%d", &Note.phone[count-1]);
                printf("Номер телефона успешно внесён в запись с номером %d\n", count);
                scanf("%c", &ccccc);
                scanf("%c", &ccccc);
                break;
            case '4':
                Note.birthday=new int*[count];
                for (int i=0; i<count; i++)
                {
                    Note.birthday[i]=new int[10];
                }
                printf("Введите дату рождения %d записи (формат: дд<пробел>мм<пробел>гггг)\n", count);
                cin>>Note.birthday[count-1][0]>>Note.birthday[count-1][1]>>Note.birthday[count-1][2];
                printf("Дата рождения успешно внесёна в запись с номером %d\n", count);
                scanf("%c", &ccccc);
                scanf("%c", &ccccc);
                break;
            case '5':
                return;
                break;
        }
    }
}
void AddDataFromKeyboard(int &count, NOTE &Note)
{
    char ccc;
    system("cls");
    while(1)
    {
        system("cls");
        printf("1.Ввод номера записи, которую вы хотите отредактировать\n");
        printf("2.Возврат в главное меню\n");
        scanf("%c", &ccc);
        switch(ccc)
        {
            case '1':
                printf("Введите номер записи, которую вы хотите отредактировать\n");
                scanf("%d", &count);
                EditRecord(count, Note);
                break;
            case '2':
                return;
                break;
        }
    }
}
void AddDataFromFile(int &count, NOTE)
{
    FILE *f;
    f=fopen("database.txt", "r");
    if (f==NULL)
    {
        printf ("Файл не открывается");
        return;
    }
    else
    {
        
    }
 
}
void PhoneSearch(int count, NOTE Note)
{
    int phone;
    bool FlagResult=0;
    printf("Введите номер телефона человека, которого вы хотите найти");
    scanf("%d",&phone);
    if (count>0)
    {
        for (int i=0; i<count; i++)
        {
            if (Note.phone[i]==phone)
            {
                printf("%d %d %d %s %s %d",Note.birthday[i][0], Note.birthday[i][1], Note.birthday[i][2], Note.family[i], Note.name[i], Note.phone[i]);
                FlagResult=1;
            }
        }
        if (FlagResult==0)
        {
            printf("Людей с таким номером в базе данных нет");
        }
    }
    else
    {
        printf("База данных пуста");
    }
}
void MonthSearch(int count, NOTE Note)
{
    int month;
    bool FlagResult=0;
    printf("Введите номер месяца рождения человека, которого вы хотите найти");
    scanf("%d",&month);
    if (count>0)
    {
        for (int i=0; i<count; i++)
        {
            if (Note.birthday[count][1]==month)
            {
                printf("%d %d %d %s %s %d", Note.birthday[count][0], Note.birthday[count][1], Note.birthday[i][2], Note.family[count], Note.name[count], Note.phone[count]);
                FlagResult=1;
            }
        }
        if (FlagResult==0)
        {
            printf("Людей с таким номером в базе данных нет");
        }
    }
    if (count<=0)
    {
        printf("База данных пуста");
    }
}
void main()
{
    setlocale(LC_ALL, "russian");
    int count;
    char c, cc;
    NOTE Note;
    system("cls");
    while(1)
    {
        system("cls");
        printf("Работа с базой данных\n\n");
        printf("1.Редактирование данных в базе данных с клавиатуры\n");
        printf("2.Ввод данных в базу данных из файла database.txt\n");
        printf("3.Поиск человека по номеру телефона\n");
        printf("4.Поиск людей по месяцу рождения\n");
        printf("5.Выход из программы\n");
        scanf("%c", &c);
        switch(c)
        {
            case '1':
                AddDataFromKeyboard(count, Note);
                break;
            case '2':
                
            case '3':
                PhoneSearch(count, Note);
                break;
            case '4':
                MonthSearch(count, Note);
                break;
            case '5':
                return;
                break;
        }
    }
}
Проблема в том, что на 35 и 47 строках кода программа почему-то пропускает эти фрагменты кода. Вопрос: почему?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.12.2011, 12:16     Программа игнорирует gets()
Посмотрите здесь:

программа игнорирует break C++
Игнорирует cin в цикле. C++
Программа игнорирует пробел. C++
C++ Строки (игнорирует getline)
C++ игнорирует строку с getline
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
-=ЮрА=-
Заблокирован
Автор FAQ
23.12.2011, 12:20     Программа игнорирует gets() #2
Цитата Сообщение от Glam_Man Посмотреть сообщение
gets(Note.family[count-1]);
- программа не игнорирует gets - после того как вы нажали Enter
Цитата Сообщение от Glam_Man Посмотреть сообщение
scanf("%c", &cccc);
у вас в буфере осталось сидеть '\n' от ввода - вот его то и считывает gets. чтобы попробовать решить проблему после scanf("%c", &cccc); поставьте getchar();

Добавлено через 1 минуту
Цитата Сообщение от Glam_Man Посмотреть сообщение
Проблема в том, что на 35 и 47 строках кода программа почему-то пропускает эти фрагменты кода. Вопрос: почему?
- я дал для кода ниже в тех строках ситуация аналогична - вытирайте '\n' из буфера посредством getchar();
Glam_Man
6 / 6 / 0
Регистрация: 15.10.2011
Сообщений: 73
23.12.2011, 13:31  [ТС]     Программа игнорирует gets() #3
-=ЮрА=-
Спасибо, помогло. Теперь нужно написать функцию чтения строк из файла формата:

21.12.2011 Ашихмин Алексей 89605123216
22.12.2011 Гусев Иван 89202561608
1.1.2011 Федотов Сергей 89151280804
...

Опишу схему присваивания на примере первой строки: 21.12.2011 должно присвоиться Note.birthday[i][0], Note.birthday[i][1] и Note.birthday[i][2] соответственно, Ашихмин в Note.family[i], Алеесей в Note.name[i] и 89605123216 в Note.phone[i], далее увеличение i до тех пор, пока оно меньше количества строк в файле. Алсо, нужно выделить память. Как это реализовывается?

Вот набросок функции:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void AddDataFromFile(int &count, NOTE &Note)
{
    FILE *f;
    f=fopen("database.txt", "r");
    if (f==NULL)
    {
        printf ("Файл не открывается");
        return;
    }
    else
    {
        while (!feof(f))
        {
            
        } 
        fclose(f); 
    }
}
Nameless One
23.12.2011, 13:47
  #4

Не по теме:

Не надо испльзовать gets — она небезопасна (и будет удалена в новом стандарте). Лучше вместо нее использовать fgets

-=ЮрА=-
Заблокирован
Автор FAQ
23.12.2011, 13:55     Программа игнорирует gets() #5
Цитата Сообщение от Glam_Man Посмотреть сообщение
Теперь нужно написать функцию чтения строк из файла формата:
21.12.2011 Ашихмин Алексей 89605123216
Тип того
C
1
2
3
4
5
char sDate[32];
char sName[32];
char sFam[32];
long lVal;
fscanf(f,"%s%s%s%u",sDate,sFam,sDate,&lVal);
Добавлено через 5 минут
Glam_Man, чтобы не было граблей с gets или fgets просто напишите вместо gets(Note.family[count-1]); scanf с продвинутым спецификатором:
scanf("%[^\n]",Note.family[count-1]) - можно ввести строку с пробелами
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
23.12.2011, 13:59     Программа игнорирует gets() #6
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Glam_Man, чтобы не было граблей с gets или fgets просто напишите вместо gets(Note.family[count-1]); scanf с продвинутым спецификатором:
scanf("%[^\n]",Note.family[count-1]) - можно ввести строку с пробелами
тут такая же проблема — потенциальная опасность переполнения буфера. Чтобы от нее избавиться при использовании scanf, нужно указать maximum field width specificator в строке формата
-=ЮрА=-
Заблокирован
Автор FAQ
23.12.2011, 14:04     Программа игнорирует gets() #7
Цитата Сообщение от Nameless One Посмотреть сообщение
тут такая же проблема — потенциальная опасность переполнения буфера. Чтобы от нее избавиться при использовании scanf, нужно указать maximum field width specificator в строке формата
- тогда
C
1
2
char text[256];
scanf("%255[^\n]",text);
просто fgets начинающие(да и я сам когда-то) воспринимают как функцию не потокового а файлового чтения...
darkknight2008
 Аватар для darkknight2008
61 / 61 / 6
Регистрация: 16.10.2011
Сообщений: 200
23.12.2011, 15:00     Программа игнорирует gets() #8
Цитата Сообщение от Glam_Man Посмотреть сообщение
Алсо, нужно выделить память. Как это реализовывается?
Сначало нужно пробежать весь файл сверху вниз, посчитать кол-во человек. Получим N - кол-во человек, далее выделим память.
C++
1
2
3
4
Note.birthday = new int[N][3];
Note.family = new char[N][MAX_STR]; // MAX_STR ты должен объявить сам
Note.name  = new char[N][MAX_STR];
Note.phone = new char[N][MAX_STR];
Далее возвращаем указатель в файле на начало и бежим по человекам...
C++
1
2
3
4
rewind(f);
for (int i = 0; i < N; i++)
  if (fscanf(f, "%i.%i.%i %s %s %s", &Note.birthday[i][0], &Note.birthday[i][1], &Note.birthday[i][2], Note.family[i], Note.name[i], Note.phone[i]) != 6)
    printf("Incorrect %i string in file!\n", i + 1);
Наверно чтото на подобии этого должно быть.
-=ЮрА=-
23.12.2011, 15:22
  #9

Не по теме:

darkknight2008, а считать время в строку не проще ли???

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
fscanf(f,"%s%s%s%u",sDate,sFam,sDate,&lVal);

darkknight2008
23.12.2011, 15:27
  #10

Не по теме:

Цитата Сообщение от Glam_Man Посмотреть сообщение
должно присвоиться Note.birthday[i][0], Note.birthday[i][1] и Note.birthday[i][2]
Как написано, так и сделал. Д и сортировку по дате проводить будет легче.

Glam_Man
6 / 6 / 0
Регистрация: 15.10.2011
Сообщений: 73
24.12.2011, 09:56  [ТС]     Программа игнорирует gets() #11
Цитата Сообщение от darkknight2008 Посмотреть сообщение
Сначало нужно пробежать весь файл сверху вниз, посчитать кол-во человек. Получим N - кол-во человек, далее выделим память.
C++
1
2
3
4
Note.birthday = new int[N][3];
Note.family = new char[N][MAX_STR]; // MAX_STR ты должен объявить сам
Note.name  = new char[N][MAX_STR];
Note.phone = new char[N][MAX_STR];
Далее возвращаем указатель в файле на начало и бежим по человекам...
Тогда такой вопрос: как посчтать количество человек в файле? Наверное надо как-то организовать цикл, который будет считать количество '\n' в файле, но я хз как
C++
1
2
3
4
rewind(f);
for (int i = 0; i < N; i++)
  if (fscanf(f, "%i.%i.%i %s %s %s", &Note.birthday[i][0], &Note.birthday[i][1], &Note.birthday[i][2], Note.family[i], Note.name[i], Note.phone[i]) != 6)
    printf("Incorrect %i string in file!\n", i + 1);
Наверно чтото на подобии этого должно быть.
rewind() что за функция?
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.12.2011, 09:59     Программа игнорирует gets() #12
Установка индикатора позиции в файле на начало файла
Glam_Man
6 / 6 / 0
Регистрация: 15.10.2011
Сообщений: 73
24.12.2011, 10:31  [ТС]     Программа игнорирует gets() #13
C++
1
2
3
4
5
while(fgetc(f!=EOF))
{
if(fgetc(f)=='\n') 
k++;
}
Подсчитает количество строк в файле?
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.12.2011, 10:35     Программа игнорирует gets() #14
Теоретически, должна была бы. Но, будет ли она работать правильно, целиком зависит от файла, т.к. на проверку приходит два считывания. Ну и проверка на конец файла совершенно неправильная.
Подсчитывать строки можно так
C
1
2
3
4
char c;
while((c = fgetc(f)) != EOF)
  if(c == '\n')
    k++;
Glam_Man
6 / 6 / 0
Регистрация: 15.10.2011
Сообщений: 73
24.12.2011, 10:58  [ТС]     Программа игнорирует gets() #15
Ок, дописал функцию
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
void AddDataFromFile(int &count, NOTE *Note)
{
    FILE *f;
    char cc;
    f=fopen("database.txt", "r");
    if (f==NULL)
    {
        printf ("Файл не открывается\n");
        return;
    }
    else
    {
        while((cc=fgetc(f))!=EOF)
        {
            if(cc=='\n') 
            count++;
        }
        rewind(f);
        Note[count].family = new char[500];
        Note[count].name  = new char[500];
        Note[count].phone = new char[500];
        for (int i=0; i<count; i++)
        {
            if (fscanf(f, "%i.%i.%i %s %s %s", &Note[i].birthday[0], &Note[i].birthday[1], &Note[i].birthday[2], &Note[i].family, &Note[i].name, &Note[i].phone)!=6)
            {
                printf("Некорректная %i строка в файле\n", i+1); 
            }
            fclose(f);
            return;
        }
    }
}
Но при вызове функции вылезает сообщение об обращении инструкции по адресу к памяти по адресу и о том, что память не может быть "written". В чём проблема?
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.12.2011, 11:06     Программа игнорирует gets() #16
скорее всего 19-21 строки — неправильно выделяешь память
C++
1
2
3
4
5
6
for(int i = 0; i < count; ++i)
{
    Note[i].family = new char[500];
    Note[i].name  = new char[500];
    Note[i].phone = new char[500];
}
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.12.2011, 11:08     Программа игнорирует gets() #17
И да — под сам массив Note память выделена?
kazak
24.12.2011, 11:29
  #18

Не по теме:

Цитата Сообщение от Nameless One Посмотреть сообщение
while((c = fgets(f)) != EOF)
может fgetc?

Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.12.2011, 11:29     Программа игнорирует gets() #19
спасибо, поправил
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.12.2011, 11:40     Программа игнорирует gets()
Еще ссылки по теме:

Программа игнорирует условия C++
Не работает gets (программа игнорирует операцию ввода) C++
Игнорирует ввод cin C++

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

Или воспользуйтесь поиском по форуму:
Glam_Man
6 / 6 / 0
Регистрация: 15.10.2011
Сообщений: 73
24.12.2011, 11:40  [ТС]     Программа игнорирует gets() #20
Цитата Сообщение от Nameless One Посмотреть сообщение
И да — под сам массив Note память выделена?
Дас
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
void AddDataFromFile(int &count, NOTE *Note)
{
    count=0;
    FILE *f;
    char cc;
    f=fopen("database.txt", "r");
    if (f==NULL)
    {
        printf ("Файл не открывается\n");
        return;
    }
    else
    {
        while((cc=fgetc(f))!=EOF)
        {
            if(cc=='\n') 
            count++;
        }
        rewind(f);
        for(int i = 0; i < count; ++i)
        {
             Note[i].family = new char[500];
             Note[i].name  = new char[500];
             Note[i].phone = new char[500];
        }
        for (int i=0; i<count; i++)
        {
            if (fscanf(f, "%i.%i.%i %s %s %s", &Note[i].birthday[0], &Note[i].birthday[1], &Note[i].birthday[2], &Note[i].family, &Note[i].name, &Note[i].phone)!=6)
            {
                printf("Некорректная %i строка в файле\n", i+1); 
            }
            fclose(f);
            return;
        }
    }
}
Поправил. Теперь проблема в том, что count подсчитывает количество строк, на 1 меньшее, чем в файле, всё из-за того, что последний символ в файле есть последний символ номера телефона последней записи. Нужно как-то сделать так, чтобы последнюю строчку count тоже сосчитал
Yandex
Объявления
24.12.2011, 11:40     Программа игнорирует gets()
Ответ Создать тему
Опции темы

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