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

Обнуляются поля в структуре - C++

Восстановить пароль Регистрация
 
ReDoX
0 / 0 / 0
Регистрация: 01.07.2015
Сообщений: 10
01.07.2015, 12:38     Обнуляются поля в структуре #1
Всем привет!
Курю книжку по плюсам от Шилдта. Домашнее задание было в книге реализовать поиск по имени товара. Вот объявление структуры.

C++
1
2
3
4
5
6
7
8
9
const size_t arraySize = 255;
 
struct InventoryType {
    char name[40];
    int onHand;
    int leadTime;
    double cost;
    double retail;
} inventory[arraySize];
Искать нужно по name. Вот функция, которая осуществляет поиск.

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 search()
{
    /*
     * Получаем искомое имя.
     */
    char *name = new char[80];
    cout << "Введите наименование товара: ";
    cin >> *name;
 
    size_t *inventoryItem = new size_t(0);
 
    for (; *inventoryItem < arraySize; ++(*inventoryItem)) {
        /*
         * Проходим по всей структуре пока не найдем соответствие,
         * если нашли, завершаем цикл.
         */
        if (!strcmp(name, inventory[*inventoryItem].name))
            break;
    }
 
    delete[] name;
 
    /*
     * Передаем на вывод то, что нашли.
     */
    display(inventoryItem);
}
В ней нет проблемы, по крайней мере я так думаю. Проблема заключается в функции вывода (display() если быть точным). Проблема в том, что все поля иногда обнуляются. Когда именно я так и не понял. Собственно функция.

C++
1
2
3
4
5
6
7
8
9
10
11
void display(size_t *inventoryItem)
{
    cout << "Имя: " << inventory[*inventoryItem].name << endl;
    cout << "Стоимость: $" << inventory[*inventoryItem].cost<< endl;
    cout << "В розницу: $" << inventory[*inventoryItem].retail << endl;
    cout << "В наличии: " << inventory[*inventoryItem].onHand << endl;
    cout << "До пополнения осталось: "
        << inventory[*inventoryItem].leadTime << " дней" << endl << endl;
 
    delete inventoryItem;
}
Тренируюсь в указателях, просьба не бранить за это

В дебаге если смотреть, то все поля в структуре равны 0 или '\0' и потом несколько раз выводится меню. Есть идеи на счет проблемы?

P.S. Если как - то не правильно задал вопрос, извините, не часто бываю на форумах.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.07.2015, 12:38     Обнуляются поля в структуре
Посмотрите здесь:

массив в структуре C++
объявление в структуре C++
C++ Суммирование в структуре
C++ список (в программе обнуляются указатели на структуры)
Сортировка в структуре C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kerry_Jr
Модератор
 Аватар для Kerry_Jr
1855 / 1651 / 574
Регистрация: 14.05.2014
Сообщений: 4,726
Записей в блоге: 1
Завершенные тесты: 5
01.07.2015, 12:44     Обнуляются поля в структуре #2
Цитата Сообщение от ReDoX Посмотреть сообщение
C++
1
display(inventoryItem);
Этого элемента не существует. На выходе из цикла inventoryItem равен 255, а такого элемента нет в массиве (0-254)
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
01.07.2015, 12:49     Обнуляются поля в структуре #3
Цитата Сообщение от ReDoX Посмотреть сообщение
size_t *inventoryItem = new size_t(0);
зачем тут использовать указатель, да ещё и на new? Просто шоб було? чем тебя не устроил бы просто size_t inventoryItem ?
ReDoX
0 / 0 / 0
Регистрация: 01.07.2015
Сообщений: 10
01.07.2015, 13:07  [ТС]     Обнуляются поля в структуре #4
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
Этого элемента не существует. На выходе из цикла inventoryItem равен 255, а такого элемента нет в массиве (0-254)
Заменил на:
C++
1
for (; *inventoryItem < (arraySize - 1); ++(*inventoryItem))
Теперь 254, все равно иногда не выдает ответ)

Добавлено через 1 минуту
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
зачем тут использовать указатель, да ещё и на new? Просто шоб було? чем тебя не устроил бы просто size_t inventoryItem ?
Тут вообще указатели не нужны, просто так, чтобы были. Просто не вижу разницы между стэком и кучей в этой программме. Если проблема все же в них, думаю, нужно будет убрать все указатели (если решение не найдется конечно же).
Kerry_Jr
Модератор
 Аватар для Kerry_Jr
1855 / 1651 / 574
Регистрация: 14.05.2014
Сообщений: 4,726
Записей в блоге: 1
Завершенные тесты: 5
01.07.2015, 13:26     Обнуляются поля в структуре #5
ReDoX, а можно увидеть весь код целиком, желательно под спойлер его спрятать.

Добавлено через 2 минуты
Цитата Сообщение от ReDoX Посмотреть сообщение
C++
1
for (; *inventoryItem < (arraySize - 1); ++(*inventoryItem))
а теперь он в условие не войдет, если будет совпадение по последнему элементу

Добавлено через 3 минуты
ReDoX, это
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    for (; *inventoryItem < arraySize; ++(*inventoryItem)) {
        /*
         * Проходим по всей структуре пока не найдем соответствие,
         * если нашли, завершаем цикл.
         */
        if (!strcmp(name, inventory[*inventoryItem].name))
            break;
    }
 
    delete[] name;
 
    /*
     * Передаем на вывод то, что нашли.
     */
    display(inventoryItem);
замените на
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    for (; *inventoryItem < arraySize; ++(*inventoryItem)) {
        /*
         * Проходим по всей структуре пока не найдем соответствие,
         * если нашли, завершаем цикл.
         */
        if (!strcmp(name, inventory[*inventoryItem].name))
        {
            /*
             * Передаем на вывод то, что нашли.
             */
            display(inventoryItem);
            break;
        }
    }
 
    delete[] name;
ReDoX
0 / 0 / 0
Регистрация: 01.07.2015
Сообщений: 10
01.07.2015, 13:49  [ТС]     Обнуляются поля в структуре #6
3 файла всего в проекте. Сначала кину hpp файлы, потом cpp.
inventory.hpp
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#pragma once
 
/*
 * Размер структуры
 */
const size_t arraySize = 255;
 
struct InventoryType {
    char name[40]; // Имя
    int onHand;    // В наличии
    int leadTime;  // Время до пополнения товара
    double cost;   // Цена
    double retail; // Розничная цена
} inventory[arraySize];
 
int menu();
void initList();
void enter();
void display();
void display(size_t *inventoryItem);
void update();
void search();
void input(size_t *inventoryItem);

main.hpp
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
#pragma once
 
/*
 * Флаг, по которому определяем, 
 * добавлять ли новую строку в начале программы или нет
 */
bool *firstTime = new bool(true);

main.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
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <Windows.h>
 
#include "main.hpp"
#include "inventory.hpp"
 
using namespace std;
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    /*
     * Обнуляем все элементы структуры
     */
    initList();
 
    while (true) {
        /*
         * Если меню выводится не в первый раз,
         * добавляем пустую строку для красоты
         */
        if (!firstTime)
            cout << endl;
        firstTime = false;
 
        switch (menu()) {
        case 'e':
            enter();
            break;
        case 'd':
            display();
            break;
        case 'u':
            update();
            break;
        case 's':
            search();
            break;
        case 'q':
            return EXIT_SUCCESS;
        }
    }
}
 
int menu()
{
    char command;
 
    do {
        cout << "(E)nter" << endl;
        cout << "(D)isplay" << endl;
        cout << "(U)pdate" << endl;
        cout << "(S)earch" << endl;
        cout << "(Q)uit" << endl << endl;
        cout << "Введите команду: ";
        cin >> command;
    } while (!strchr("edusq", tolower(command)));
 
    return tolower(command);
}
 
void initList()
{
    /*
     * Все элементы структуры теперь равны '\0'
     */
    for (size_t *i = new size_t(0); *i < arraySize; ++(*i))
        *inventory[*i].name = '\0';
}
 
void enter()
{
    size_t *inventoryItem = new size_t(0);
 
    /*
     * Ищем свободную яичейку для записи, т.е. проверяем не равно ли имя 0
     */
    for (; *inventoryItem < arraySize; ++(*inventoryItem)) {
        if (!*inventory[*inventoryItem].name)
            break;
    }
 
    /*
     * Больше некуда записывать
     */
    if (*inventoryItem == arraySize) {
        cout << "Список полон." << endl;
 
        delete inventoryItem;
 
        return;
    }
 
    input(inventoryItem);
}
 
void display()
{
    /*
     * Выводим все элементы структуры
     */
    for (byte inventoryItem = 0; inventoryItem < arraySize; ++inventoryItem) {
        if (*inventory[inventoryItem].name) {
            cout << "Имя: " << inventory[inventoryItem].name << endl;
            cout << "Стоимость: $" << inventory[inventoryItem].cost << endl;
            cout << "В розницу: $" << inventory[inventoryItem].retail << endl;
            cout << "В наличии: " << inventory[inventoryItem].onHand << endl;
            cout << "До пополнения осталось: "
                << inventory[inventoryItem].leadTime << " дней" << endl << endl;
        }
    }
}
void display(size_t *inventoryItem)
{
    /*
     * Выводим определенную яичейку структуры
     */
    cout << "Имя: " << inventory[*inventoryItem].name << endl;
    cout << "Стоимость: $" << inventory[*inventoryItem].cost << endl;
    cout << "В розницу: $" << inventory[*inventoryItem].retail << endl;
    cout << "В наличии: " << inventory[*inventoryItem].onHand << endl;
    cout << "До пополнения осталось: "
        << inventory[*inventoryItem].leadTime << " дней" << endl << endl;
 
    delete inventoryItem;
}
 
void update()
{
    /*
     * Получаем искомое имя
     */
    char *name = new char[80];
    cout << "Введите наименование товара: ";
    cin >> *name;
 
    size_t *inventoryItem = new size_t(0);
 
    /*
     * Ищем по имени то, что дал пользователь
     */
    for (; *inventoryItem < (arraySize - 1); ++(*inventoryItem)) {
        if (!strcmp(name, inventory[*inventoryItem].name))
            break;
    }
 
    delete[] name;
 
    cout << "Введите новую информацию." << endl;
 
    /*
     * Меняем значения в уже существующей яичейке
     */
    input(inventoryItem);
}
 
void search()
{
    /*
     * Получаем искомое имя.
     */
    char *name = new char[80];
    cout << "Введите наименование товара: ";
    cin >> *name;
 
    size_t *inventoryItem = new size_t(0);
 
    for (; *inventoryItem < (arraySize - 1); ++(*inventoryItem)) {
        /*
         * Проходим по всей структуре пока не найдем соответствие,
         * если нашли, завершаем цикл.
         */
        if (!strcmp(name, inventory[*inventoryItem].name)) {
            /*
            * Передаем на вывод то, что нашли.
            */
            display(inventoryItem);
            break;
        }
    }
 
    delete[] name;
}
 
void input(size_t *inventoryItem)
{
    cout << "Товар: ";
    cin >> inventory[*inventoryItem].name;
 
    cout << "Стоимость: ";
    cin >> inventory[*inventoryItem].cost;
 
    cout << "Розничная цена: ";
    cin >> inventory[*inventoryItem].retail;
 
    cout << "В наличии: ";
    cin >> inventory[*inventoryItem].onHand;
 
    cout << "Время до пополнения запасов (в днях): ";
    cin >> inventory[*inventoryItem].leadTime;
 
    delete inventoryItem;
}


Поменял как вы сказали, ничего не изменилось. Просто я скопировал код из похожего метода, где все работает. Поэтому я не думаю что там что - то не так. Правда забыл убрать (arraySize - 1), но пока до последнего же элемента дело не дошло
Kerry_Jr
Модератор
 Аватар для Kerry_Jr
1855 / 1651 / 574
Регистрация: 14.05.2014
Сообщений: 4,726
Записей в блоге: 1
Завершенные тесты: 5
01.07.2015, 13:57     Обнуляются поля в структуре #7
Цитата Сообщение от ReDoX Посмотреть сообщение
C++
1
cin >> *name;
вот это я проглядел. Звездочку уберите

Добавлено через 1 минуту
а вообще желательно (если в названии есть пробелы) так
C++
1
getline(name, 80);
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
01.07.2015, 14:00     Обнуляются поля в структуре #8
Я ещё раз хочу спросить, зачем ты с упоротой упорностью пытаешься впихнуть везде указатели?
вот это зачем тебе? size_t *inventoryItem = new size_t(0);
а вот это зачем? bool *firstTime = new bool(true);
в смысле, нафига тут указатели вообще? Убери их! Ты только программу захламляешь!
ReDoX
0 / 0 / 0
Регистрация: 01.07.2015
Сообщений: 10
01.07.2015, 15:46  [ТС]     Обнуляются поля в структуре #9
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
вот это я проглядел. Звездочку уберите

Добавлено через 1 минуту
а вообще желательно (если в названии есть пробелы) так
C++
1
getline(name, 80);
Там же массив char, там нет такой перезагрузки, пишет ошибку. А звездочку почему убрать?

Добавлено через 37 секунд
Чего плохого в указателях? Звездочки звездочками, красиво же

Добавлено через 3 минуты
Нашел ошибку, она была вот тут
C++
1
2
3
if (!firstTime)
    cout << endl;
firstTime = false;
Так как firstTime указатель, нужно брать его значение, а не адрес. Он видимо пересекался в памяти с чем - то из структуры. Вот так пофиксил:
C++
1
2
3
if (!(*firstTime))
    cout << endl;
*firstTime = false;
P.S. Указатели зло
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
01.07.2015, 16:00     Обнуляются поля в структуре #10
Цитата Сообщение от ReDoX Посмотреть сообщение
P.S. Указатели зло
серьёзно? Может потому, что ты их совершенно не к месту используешь?
Я тебя с самого начала спросил, зачем тут вообще указатель у тебя?
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
а вот это зачем? bool *firstTime = new bool(true);
ReDoX
0 / 0 / 0
Регистрация: 01.07.2015
Сообщений: 10
01.07.2015, 16:04  [ТС]     Обнуляются поля в структуре #11
Я просто к слову, что ошибка была совсем в другом месте, а не в том в котором я искал. А указатели везде попихал, просто чтобы посмотреть что будет, поведение программы не изменилось, вернул версию без указателей.
А так указатели хороши как не крути)
Kerry_Jr
Модератор
 Аватар для Kerry_Jr
1855 / 1651 / 574
Регистрация: 14.05.2014
Сообщений: 4,726
Записей в блоге: 1
Завершенные тесты: 5
01.07.2015, 16:14     Обнуляются поля в структуре #12
Цитата Сообщение от ReDoX Посмотреть сообщение
А звездочку почему убрать?
потому что разыменованный указатель на массив символов есть не что иное, как первый элемент массива.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.07.2015, 00:06     Обнуляются поля в структуре
Еще ссылки по теме:

Функции в структуре C++
C++ Обнуляются значения вектора
Поиск в структуре C++

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

Или воспользуйтесь поиском по форуму:
ReDoX
0 / 0 / 0
Регистрация: 01.07.2015
Сообщений: 10
02.07.2015, 00:06  [ТС]     Обнуляются поля в структуре #13
В общем, проблему решил, как выше написал. Всем спасибо за помощь и впредь больше не буду использовать столько указателей)
Yandex
Объявления
02.07.2015, 00:06     Обнуляются поля в структуре
Ответ Создать тему
Опции темы

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