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

Динамическая структура данных (Стек) - C++

Восстановить пароль Регистрация
 
PNTSPro
0 / 0 / 0
Регистрация: 22.11.2014
Сообщений: 7
21.06.2015, 11:06     Динамическая структура данных (Стек) #1
Подскажите в чем ошибка, пожалуйста. Программа выдает ошибку ("Прекращена работа программы.."), когда выбираю "y" (добавление элементов структуры из бинарного файла).
Часть кода:

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
#include <fstream>
#include <iostream>
#include <cstring>
#include <cstdlib>
#define database "db.bin"
 
using namespace std;
 
ifstream fin;
ofstream fout;
 
struct work{
    char adres[25];  //адресс
    char type[25];  //тип работ
    int price;    //стоимость работ
    int time;      //время работы
    char name[80];  //фамилия ответсвенного
}data;
 
struct STACK {
    work info;
    STACK *next;
};
 
void Add(STACK **pstack)  //Ввод элемента в вершину стека
{
    char file[2];
    do{
    cout << "Добавление элементов из файла?(y/n): ";
    cin >> file;
    } while(strcmp(file,"y") && strcmp(file,"n"));
    if(!strcmp(file,"n"))
    {
        STACK *tmp = new STACK;
        cout << "\nАдрес: ";
        cin >> tmp->info.adres;
        cout << "\nТип работ: ";
        cin >> tmp->info.type;
        cout << "\nСтоимость работы: ";
        cin >> tmp->info.price;
        cout << "\nВремя работы: ";
        cin >> tmp->info.time;
        cout << "\nфамилия ответсвенного: ";
        cin >> tmp->info.name;
        tmp->next=*pstack;
        *pstack=tmp;
    } else {
        fin.open(database,ios::binary);
        if (fin.is_open())
        {
            char buf;
            int i=0;
            int count;
            while (!fin.eof())
            {
                fin.read(&buf,1);
                if (buf=='\n') i++;
            }
            fin.clear();
            fin.seekg(0, fin.beg);
            count = i / 5;
            cout << "Добавленно элементов: "<< count <<"\n";
            for(i = 0; i < count; i++)
            {
                STACK *tmp= new STACK;
                fin >> tmp->info.adres;
                fin >> tmp->info.type;
                fin >> tmp->info.price;
                fin >> tmp->info.time;
                fin >> tmp->info.name;
                tmp->next=NULL;
                (*pstack)->next=tmp;
                *pstack=tmp;
            }
        fin.close();
        }
        else
        {
            cout << "Ошибка открытия файла.";
        }
    }
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.06.2015, 11:06     Динамическая структура данных (Стек)
Посмотрите здесь:

C++ Динамическая структура данных С++
Динамическая структура данных C++
C++ Динамическая структура данных
Динамическая структура данных в С++ C++
C++ Полустатическая структура данных стек.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
yuyaryshev
18 / 18 / 6
Регистрация: 21.06.2015
Сообщений: 34
21.06.2015, 11:54     Динамическая структура данных (Стек) #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
По сути вашего вопроса ответить трудно, поскольку нет того места кода откуда вызывается функция Add.
Падение программы может быть если, например, в эту функцию передать nullptr (ну или просто ноль).

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


Эта структура называется не стек, singly-linked list и она есть в стандартной библиотеке:
http://en.cppreference.com/w/cpp/container/forward_list

Выглядеть будет так:
std::forward_list<work> work_list;

Функция Add будет выглядеть так:

... Add(std::forward_list<work>& work_list)
{
...
// Там где добавляем новый элемент
work_list.push_front(tmp);
...
}

Вывод элементов можно организовать циклом:

for(auto elem : work_list)
{
cout << elem.name;
}

Если заменить на стандартную библиотеку возможно ошибка "пройдет" .
PNTSPro
0 / 0 / 0
Регистрация: 22.11.2014
Сообщений: 7
21.06.2015, 12:28  [ТС]     Динамическая структура данных (Стек) #3
yuyaryshev, почему же это не стек, если элементы структуры добавляются в вершину?
тут я вызываю функцию добавление элемента:

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
int main()
{
    setlocale(LC_ALL,"Russian");
 
    STACK *stack = NULL;
    int otv; 
    do
    {
        cin >> otv;
        system("CLS");
        switch(otv)
        {
            case 1:
                    Add(&stack);
            break;
 
            default:
                cout << endl << "Ошибка!" << endl;
            break;
        }
    }while(otv!='0');
 
    cin.get();
}
yuyaryshev
18 / 18 / 6
Регистрация: 21.06.2015
Сообщений: 34
21.06.2015, 13:48     Динамическая структура данных (Стек) #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
По поводу поиска ошибки я уже писал, что нужно смотреть где именно оно падает при помощи дебагера.
Также предлагаю в начале немного причесать код, в любом случае он станет более читабельным и наглядным, будет легче искать ошибку и меньше шансов допустить новые.


Почему не стек:
- По принципу использования - ты просто хочешь хранить список записей push и pop в задаче работы с базой задач не актуальны
- По функциям работы с ним: у тебя Add, а не push и pop
Кстати, если нужен именно стек, он в стандартной библиотеке также есть: http://www.cplusplus.com/reference/stack/stack/
Ну это так, отступление от темы.


Что по исходникам:
Все что связанно с классом засунуть в сам класс - так будет гораздо проще искать ошибки и дописывать программу.
О чем я конкретно:
- Сейчас у тебя дублируется код: ты два раза описал, как ты добавляешь в стек (в случае из файла и в случае прямого ввода)
- Поэтому у тебя два раза будет встречаться инициализация поля next класса STACK - это не правильно, код не должен дублироваться
=> Нужно вынести функции работы со стеком в сам класс, получиться вот так:

struct STACK {
work info;
STACK* next = nullptr; // Инициализация один раз, там где она и должна быть

STACK* push_new() // Один раз описали функцию вставки нового элемента
{
STACK* tmp = new STACK();
tmp->next = next;
next = tmp;
return next;
};

STACK* pop() // Один раз описали функцию извлечения элемента
{
STACK* result = next;
if(next)
next = next->next;
return result;
};
};
// Просмотр стека без извлечения элементов будет выглядеть так
// for(auto it = начало_стека; it = it->next; it != nullptr)
// {
// }

Далее:
- Сейчас функции работы с work у тебя также в теле программы. Но по смыслу они привязаны именно к классу.
Почему я так решил?
Потому что если ты захочешь добавить/убрать/изменить поле в класс work, то тебе придется менять код в совсем других частях программы - как вводятся данные, как загружаются.
Сейчас класс в одном месте, а ввод его в другом. Можно в одном поменять, в другом забыть.

Предложение сделать так:

struct work{ // Инициализацию полей лучше добавить, в C++ она совсем не лишняя
char adres[25] = 0; //адресс
char type[25] = 0; //тип работ
int price = 0; //стоимость работ
int time = 0; //время работы
char name[80] = 0; //фамилия ответсвенного

void input()
{
cout << "\nАдрес: ";
cin >> adres;
cout << "\nТип работ: ";
cin >> type;
cout << "\nСтоимость работы: ";
cin >> price;
cout << "\nВремя работы: ";
cin >> time;
cout << "\nфамилия ответсвенного: ";
cin >> name;
};

void print()
{
cout << "\nАдрес: ";
cout << adres;
cout << "\nТип работ: ";
cout << type;
cout << "\nСтоимость работы: ";
cout << price;
cout << "\nВремя работы: ";
cout << time;
cout << "\nфамилия ответсвенного: ";
cout << name;
};

void load(ifstream& fin)
{
fin >> adres;
fin >> type;
fin >> price;
fin >> time;
fin >> name;
};

void save(ofstream& oin)
{
// TODO
};
};

Результат такой переделки:
отделить мух от котлет, станет проще искать ошибки и развивать прогу.

Добавлено через 8 минут
Код не запускал, где то мог что-то мелкое напутать.
Написал для примера, для понимания как можно разделить прогу на классы.

Потом увидел вот ошибку:
// Просмотр стека без извлечения элементов будет выглядеть так
// for(auto it = начало_стека; it != nullptr; it = it->next)
// {
// }

Добавлено через 4 минуты
Кстати под темой внизу приведены похожие. Там походу решение твоей задачи).
PNTSPro
0 / 0 / 0
Регистрация: 22.11.2014
Сообщений: 7
21.06.2015, 14:34  [ТС]     Динамическая структура данных (Стек) #5
yuyaryshev, спасибо)
Yandex
Объявления
21.06.2015, 14:34     Динамическая структура данных (Стек)
Ответ Создать тему
Опции темы

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