Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
PNTSPro
0 / 0 / 0
Регистрация: 22.11.2014
Сообщений: 7
1

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

21.06.2015, 11:06. Просмотров 1069. Ответов 4
Метки нет (Все метки)

Подскажите в чем ошибка, пожалуйста. Программа выдает ошибку ("Прекращена работа программы.."), когда выбираю "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 << "Ошибка открытия файла.";
        }
    }
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.06.2015, 11:06
Ответы с готовыми решениями:

Динамическая структура "Стек". Обновить значение элемента
Искал в интеренете везде только добавление есть #include &lt;iostream&gt; ...

Динамическая структура данных в С++
Определить функции вставки нового звена в односвязный линейный список, удаления...

Динамическая структура данных
Нужна помощь с динамическими структурами данных: Написать программу, которая...

Динамическая структура данных С++
Всем огромный привет! :) Начали учить эту тему, ещё до конца не разобрался, а...

Динамическая структура данных
Дано type строка=array of char; дата=record число:1..31; месяц:1..12;...

4
yuyaryshev
18 / 18 / 6
Регистрация: 21.06.2015
Сообщений: 34
21.06.2015, 11:54 2
Лучший ответ Сообщение было отмечено PNTSPro как решение

Решение

По сути вашего вопроса ответить трудно, поскольку нет того места кода откуда вызывается функция 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;
}

Если заменить на стандартную библиотеку возможно ошибка "пройдет" .
0
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();
}
0
yuyaryshev
18 / 18 / 6
Регистрация: 21.06.2015
Сообщений: 34
21.06.2015, 13:48 4
Лучший ответ Сообщение было отмечено PNTSPro как решение

Решение

По поводу поиска ошибки я уже писал, что нужно смотреть где именно оно падает при помощи дебагера.
Также предлагаю в начале немного причесать код, в любом случае он станет более читабельным и наглядным, будет легче искать ошибку и меньше шансов допустить новые.


Почему не стек:
- По принципу использования - ты просто хочешь хранить список записей 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 минуты
Кстати под темой внизу приведены похожие. Там походу решение твоей задачи).
0
PNTSPro
0 / 0 / 0
Регистрация: 22.11.2014
Сообщений: 7
21.06.2015, 14:34  [ТС] 5
yuyaryshev, спасибо)
0
21.06.2015, 14:34
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.06.2015, 14:34

Динамическая структура данных
Есть динамическая структура struct comp { char num; comp* next; //Ссылка...

Динамическая структура данных Очередь
Определить новую динамическая структуру данных(очередь на основе линейно -...

Динамическая структура данных. Что это?
В требованиях к одной вакансии Динамическая структура данных. Цитата из Прата...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

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