Динамические структуры в c++

308
06 сентября 2017, 14:52

Прохожу задание в книге Алекса Эллайна. После темы указателей и ссылок в одном из проверочных заданий, он просит написать написать программу со списком контактов. Обязательное условие, что бы структура была динамической. Я написал код. Но у меня есть проблема с созданием динамической структуры. Суть моей проблемы в том, что я не могу организовать логику программы и не знаю в какой конкретно момент лучше всего объявить динамическую переменную для работы со структурой. Ниже я прикладываю свой код. В целом, код компилируется и запускается. Но, после того, как заполнить информацию о контактах и попросить их показать, то будет выведено только количество контактов, но поля будут абсолютно пустыми. Так же, я запускал код в режиме отладки и всё равно не могу понять, в какой момент переменные из цикла, скажем так "теряются".

    #include <iostream>
using namespace std;
//Собственно, сама структура
struct People
{
    string UName;
    string UJob;
    int UPhone;
};
int pins = 0; //В этой переменной хранится информация о том, сколько в сумме имеется записей в книжке
int main() // Точка входа в программу
{
    //Сперва, мы взаимодействуем с пользователем. Спрашиваем у него, что конкретно он хочет сделать
    int action; //Переменная, которая помнит выбор пользователя
    cout << "\nWelcome to Contact app. \n\n" <<
            "1 - Show contact list.\n" <<
            "2 - Add new contact.\n\n" <<
            "Your action: ";
    cin >> action; //Реагируем на действия
    switch (action)
    {
    case 1:
        // Цикл 1. Если количество записей ноль, то пишем уведомление.
        if (pins == 0)
        {
            cout << "Contact list empty...\n";
            main();
        }
        else
            //Если есть записи, то выводим их на экран
        {
            People My_people[pins];
            for (int i = 0; i < pins; i++)
            {
                cout << "Name: " << My_people[i].UName << '\n' <<
                        "Job: " << My_people[i].UJob << '\n' <<
                        "Phone number: " << My_people[i].UPhone << '\n';
            }
            //Конец цикла 1.
        }
        main(); //Выходим в начало программы
        break;
    case 2:
        //Добавляем контакты
        //Объявляем необходимые переменные.
        int NewContact;
        string name;
        string job;
        int PN;
        //Спрашиваем, сколько будет новых контактов
        cout << "How many new contacts do you want to add?\n";
        cin >> NewContact;
        //Заполняем поля в цикле столько раз, сколько указано указано в переменной выше
        for (int i = 0; i < NewContact; i++)
        {
            cout << "Name new contact: \n";
            cin >> name;
            cout << "As whom does " << name << " work?\n";
            cin >>  job;
            cout << name << " phone number: \n";
            cin >> PN;
            pins = pins + 1; //Увеличиваем на 1 количество записей.
        }
        //Добавляем данные в динамическую структуру. Так как неизвестно сколько по факту будет новых пользователей
        People *my_people = new People[NewContact];
        //Копируем по одном введённую выше в структуру.
        for (int i = 0; i < pins; i++)
        {
            my_people[i].UName = name;
            my_people[i].UJob = job;
            my_people[i].UPhone = PN;
        }
        delete[] my_people;
            main(); //Выходим в главное меню
        break;
    }
}

Результат работы кода можно посмотреть по ссылке:

http://cpp.sh/8nj6k

Когда я делаю нечто подобное, без всяких ветвлений Switch (своего рода облегчённый вариант), то код работает нормально. Даже если его загнать в цикл Do While и выполнять произвольное количество раз.

#include <iostream>
using namespace std;
struct People
{
    string name;
    int health;
};
int main ()
{
    int action;
    cout << "Enter how much new player: \n";
    cin >> action;
    People *my_people = new People[action];
    for (int i = 0; i < action; i++)
    {
        cout << "NAme: \n";
        cin >> my_people[i].name;
        cout << "health int \n";
        cin >> my_people[i].health;
    }
    for (int i = 0; i < action; i++)
    {
        cout << "result: \n";
        cout << my_people[i].name << '\n' <<
                my_people[i].health << '\n';
    }
    delete[] my_people;
    system("pause");
}
Answer 1
//Добавляем данные в динамическую структуру. Так как неизвестно сколько по 
 факту будет новых пользователей
People *my_people = new People[NewContact];

Данные добавляете в массив my_people;

People My_people[pins];
for (int i = 0; i < pins; i++)
{
    cout << "Name: " << My_people[i].UName << '\n' <<
                    "Job: " << My_people[i].UJob << '\n' <<
                    "Phone number: " << My_people[i].UPhone << '\n';
}

Объявили пустой массив My_people на pins элементов и сразу пытаетесь вывести значения. Это разные массивы, они ничего не знаю друг о друге.

Как и в втором Вашем варианте, необходимо в начале функции main() объявить

People *my_people = new People[size];

и работать только с ним.

По поводу этого кода

    int NewContact;
    string name;
    string job;
    int PN;
    //Спрашиваем, сколько будет новых контактов
    cout << "How many new contacts do you want to add?\n";
    cin >> NewContact;
    //Заполняем поля в цикле столько раз, сколько указано указано в переменной выше
    for (int i = 0; i < NewContact; i++)
    {
        cout << "Name new contact: \n";
        cin >> name;
        cout << "As whom does " << name << " work?\n";
        cin >>  job;
        cout << name << " phone number: \n";
        cin >> PN;
        pins = pins + 1; //Увеличиваем на 1 количество записей.
    }
    //Добавляем данные в динамическую структуру. Так как неизвестно сколько по факту будет новых пользователей
    People *my_people = new People[NewContact];
    //Копируем по одном введённую выше в структуру.
    for (int i = 0; i < pins; i++)
    {
        my_people[i].UName = name;
        my_people[i].UJob = job;
        my_people[i].UPhone = PN;
    }
    delete[] my_people;

Вы в цикле записываете значения в переменные string name; string job; int PN, каждый раз затирая старые значения. А затем в отдельном цикле добавляете экземпляры класса People в массив с одинаковыми значениями. Вот возможное решение:

int NewContact;
string name;
string job;
int PN;
//Спрашиваем, сколько будет новых контактов
cout << "How many new contacts do you want to add?\n";
cin >> NewContact;
People *my_people = new People[NewContact];
//Заполняем поля в цикле столько раз, сколько указано указано в переменной выше
for (int i = 0; i < NewContact; i++)
{
    cout << "Name new contact: \n";
    cin >> name;
    cout << "As whom does " << name << " work?\n";
    cin >>  job;
    cout << name << " phone number: \n";
    cin >> PN;
    pins = pins + 1; //Увеличиваем на 1 количество записей.
    my_people[i].UName = name;
    my_people[i].UJob = job;
    my_people[i].UPhone = PN;
}
READ ALSO
Error C2075 при инициализации массива

Error C2075 при инициализации массива

Вы пытаетесь захватить info по значению, а так нельзя - это массивЗахватывайте по ссылке - &info

262
Конвертация YAW PITCH ROLL в траекторию для UE4

Конвертация YAW PITCH ROLL в траекторию для UE4

У меня есть массив данных (YPR) снятый с показаний гироскопа при его движении по определенной траектории (примерно по 100 значений на секунду)Я...

256
class перед возвращаемым типом

class перед возвращаемым типом

Зачем пишут class перед возвращаемым типом?

242
Как сделать прокрутку списка ul&gt;li

Как сделать прокрутку списка ul>li

Как сделать прокрутку списка при нажатии на кнопки и при скролингеможет есть готовые решение или слайдеры?!

214