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

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

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

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

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

Динамическая структура "Стек". Обновить значение элемента - C++
Искал в интеренете везде только добавление есть #include &lt;iostream&gt; /*НАША СТРУКТУРА*/ struct List { int x;...

Динамическая структура данных - C++
Нужна помощь с динамическими структурами данных: Написать программу, которая сохраняет элементы с помощью динамической структуры...

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

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

Динамическая структура данных - C++
Есть динамическая структура struct comp { char num; comp* next; //Ссылка на следущий элемент списка }; struct dyn_list {...

Динамическая структура данных - C++
Дано type строка=array of char; дата=record число:1..31; месяц:1..12; год:1900..1979 end;анкета=record фамилия:строка;пол:(муж,...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
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, спасибо)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.06.2015, 14:34
Привет! Вот еще темы с ответами:

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

некорректно работает динамическая структура данных с++ - C++
Взял пример с книги, которая одобренная министерством образования. А код работает не совсем правильно. Не могу найти ошибку, подскажите в...

Динамическая структура данных. Что это? - C++
В требованиях к одной вакансии Динамическая структура данных. Цитата из Прата С. 189 стр.: &quot;Инструментом для этого, опять-таки,...

Полустатическая структура данных стек. - C++
Оформить структуру данных в виде полустатической структуры стека для списка учебной группы Разработать программу, осуществляющую : ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
21.06.2015, 14:34
Ответ Создать тему
Опции темы

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