Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как создать и работать с массивом указателей структуры ?

66K
25 мая 2011 года
Antosh
18 / / 25.05.2011
Читал статьи по структурам и главы в книгах, но никак не могу толком разобраться, помогите пожалуйста.
К примеру есть структура:
 
Код:
struct s{
  int a;
  int b;
  char c[20];
}

1 - Как создать массив указателей на элементы этой структуры? Так как мне нужно создавать элементы динамически при считывании инфы из файла.
2 - Как выделять память под каждый новый элемент массива структуры этой?

Очень срочно нужна помощь, за ранее спасибо.
277
25 мая 2011 года
arrjj
1.7K / / 26.01.2011
s * array=new s[количество_структур];
количество_структур можешь получить сразу прочитав размер файла и разделив на размер структуры (sizeof(s)) т.к. размер уструктуры у тубя фиксированный.
обращение к элементу array[индекс_структуры].a
удаление delete [] array;
А читать надо было не про структуры а про указатели
66K
25 мая 2011 года
Antosh
18 / / 25.05.2011
спасибо.
а что мне делать при добавлении в программе еще одного элемента структуры? Тупо переписывать имеющийся массив структур в новую созданную структура с размером +1 ? или можно как-то сделать красивее, к примеру типа использования realloc() ?
277
25 мая 2011 года
arrjj
1.7K / / 26.01.2011
Лучше и правильней конечно через new и копированием элементов, но можно и так:
 
Код:
array=(s*)realloc(s,новое_количество_структур*sizeof(s));


Ну а можно ещё например через std::vector это сделать - попроще будет.
66K
25 мая 2011 года
Antosh
18 / / 25.05.2011
что-то не получается...
вот объявляю структуру и указатель на нее
Код:
struct Flight
{
  int id;
  int day;
  int month;
  int year;
  int hour;
  int minute;
  char route[26];
  int price;
  int totalPlaces;
  int busyPlaces;
}*flight;

выделяю под нее память (под 3 элемента) - выделяется вроде норм
 
Код:
flight=(Flight *)new (struct Flight[3]);

считываю данные из файла - считывается без ошибок
считанные данные заносятся в структуру по след образцу, N - это число элементов в структуре, оно увеличивается на +1 при записи новой строки из файла, то есть при добавлении нового элемента в массив структур
 
Код:
this->flight[N-1].day=day;

но при выводе структуры на экран выводится ерунда какая-то
нормально выводятся только данные из последней прочитанной строки, но они разбросаны по всем 3 элементам массива структур, а в остальных элементах структур мусор выводится

возможно не совсем понятно объяснил, но все же HELP ME )
277
25 мая 2011 года
arrjj
1.7K / / 26.01.2011
Покажи больше кода.
316
25 мая 2011 года
Alm3n
889 / / 29.05.2009
flight - указатель на 1 элт структуры, а не на массив. очевидно, что new может выделять участки памяти, идущие не по порядку.
66K
26 мая 2011 года
Antosh
18 / / 25.05.2011
в общем у меня получилось замутить хранение через указатель flight (не массив указателей), правда работает глючно так как, как писал Alm3n (с опечаткой) new выделяет память только последовательно, а не так как realloc.

Цитата:
arrjj Ну а можно ещё например через std::vector это сделать - попроще будет.


решил последовать вашему совету и использовать для массива структур vector.

подскажите пожалуйста как мне объявить vector на структуру и каким будет обращение к нему, если я правильно понимаю то будет так:

Код:
struct Flight
{
  int id;
  int day;
  int month;
  int year;
  int hour;
  int minute;
  char route[26];
  int price;
  int totalPlaces;
  int busyPlaces;
}*flight;
vector <Flight> *f;
f.day=10;


при таком объявлении у меня уже будет массив структур типа Flight в векторе или нет? %)
278
26 мая 2011 года
Alexander92
1.1K / / 04.08.2008
1. Почитай в принципе о структурах данных. Списки, очереди и т.п. Многое понятнее станет.
2. Зачем тебе указатель на вектор? Тебе нужен собственно вектор:
Код:
typedef struct tagFlight {
  int id;
  int day;
  int month;
  int year;
  int hour;
  int minute;
  char route[26];
  int price;
  int totalPlaces;
  int busyPlaces;
} FLIGHT, *LPFLIGHT;

vector<FLIGHT> flights(размер_массива);


[QUOTE=Antosh]
при таком объявлении у меня уже будет массив структур типа Flight в векторе или нет? %)
[/QUOTE]
Вектор - это и есть, по сути, массив. Только обернутый в класс.

P.S. Какая конечная цель?
66K
26 мая 2011 года
Antosh
18 / / 25.05.2011
спс, сам уже тоже понял что мне нужен сам вектор, а не указатель на него) а про структуры данных уже тоже читаю, но пока непонятны некоторые моменты

подскажите как правильно объявлять структуру для компилятора VS 2008. На мое объявление он пишет:
Цитата:
error C2351: устаревший синтаксис инициализации конструктора C++


вот мое объявление:

 
Код:
Flight(int _id, int _day, int _month, int _year, int _hour, int _minute, char _route[26], int _price, int _tp, int _bp):
(id(_id), day(_day), month(_month), year(_year), hour(_hour), minute(_minute), route(_route), price(_price), totalPlaces(_tp), busyPlaces(_bp)){}

и еще ругается на это же объявление:
Цитата:
error C2064: результатом вычисления фрагмента не является функция, принимающая 1 аргументов



Конечная цель: читать из файла инфу и писать ее в вектор структур, затем с ней что-то делать (добавлять, удалять, изменять) и писать измененный вектор структур в файл.

278
26 мая 2011 года
Alexander92
1.1K / / 04.08.2008
Во-первых, то, что вы написали, - это не объявление, а инициализирующий конструктор (который может быть объявлен только внутри самой структуры). Во-вторых - у вас там лишние внешние скобки.
 
Код:
Flight (int _id, int _day, int _month) : id(_id), day(_day), month_day() {} // и т.д., все остальные члены.

В третьих, route лучше копируйте целиком, а не просто указатель переписывайте.
66K
26 мая 2011 года
Antosh
18 / / 25.05.2011
Невнимательный) скобки убрал, спс, заработал.
Вместо char[26] сделаю наверное string.

Но появилась новая проблема)

Если убрать конструктор инициализации структуры, то могу сделать vector.resize(5); (к примеру)
А вот если он есть, то vector.resize(5); уже не проходит, пишет ошибку:
Цитата:
error C2512: Schedule::Flight::Flight: нет подходящего конструктора по умолчанию
1> c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector(712): при компиляции функции-члена "<Нет данных>" класса <Нет данных>



как мне в данном случае с наличием конструктора инициализации структуры увеличивать размер вектора ?

277
26 мая 2011 года
arrjj
1.7K / / 26.01.2011
std::vector::push_back или добавить пустой конструктор Flight::Flight(){};
278
26 мая 2011 года
Alexander92
1.1K / / 04.08.2008
Все правильно. vector::resize() пытается вызывать конструктор по умолчанию, которого у вас нет. Напишите
 
Код:
Flight(/* без параметров! */) {}


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

P.S. arrjj, опередил.)
66K
26 мая 2011 года
Antosh
18 / / 25.05.2011
2 arrjj & 2 Alexander92 Спасибо вам за помощь и советы, пока все работает. Буду мутить дальше, если возникнут вопросы, отпишусь в эту тему.
66K
26 мая 2011 года
Antosh
18 / / 25.05.2011
подскажите еще:
я перегружаю операторы << и >> для потокового чтения и записи файл. Каким образом мне обращаться к конкретному элементу в структуре для того чтобы изменить именно его значение? (к примеру нужно изменить только день)

В общей сложности у меня есть еще класс Schedule :), в котором и находятся структура и вектор, а также методы для работы с элементами структуры:
Код:
class Schedule
{
private:
    struct Flight
    {
        int id;
        int day;
        int month;
        int year;
        int hour;
        int minute;
        string route;
        int price;
        int totalPlaces;
        int busyPlaces;

        Flight(){};
        Flight (int _id, int _day, int _month, int _year, int _hour, int _minute, string _route, int _price, int _tp, int _bp): id(_id), day(_day), month(_month), year(_year), hour(_hour), minute(_minute), str(_route), price(_price), totalPlaces(_tp), busyPlaces(_bp){}
    };
    vector <Flight> vecf;
   
public:
    Schedule();
    void ReadFile(); //загрузка расписания из файла
    void WriteFile(); //выгрузка вектора в файл
    void AddFlight(); //добавить рейс
    void EditFlight(); //редактировать рейс
    void DelFlight(); //удалить рейс
    void ShowFlight(int i); //вывод одного рейса
    void ShowFlights(); //вывод всех рейсов
    //void FindFlightOnDate(); //найти рейсы по дате
    void FindFlightOnRoute(); //найти рейсы по направлению
    void NextFlight(); //ближайшие рейсы, 3-4 рейса которые соответствуют маршруту  
    int CheckDate(char b[11]); //проверка даты на правильность
    int CheckTime(char b[6]); //проверка времени на правильность

    void SetId(int id){}
    int GetId(){}
    void SetDay(int day){}
    int GetDay(){}
    void SetMonth(int month){}
    int GetMonth(){}
    void SetYear(){}
    int GetYear(){}
    void SetHour(int hour){}
    int GetHour(){}
    void SetMinute(int id){}
    int GetMinute(){}
    void SetRoute(string route){}
    char* GetRoute(){}
    void SetPrice(int Price){}
    int GetPrice(){}
    void SetTotalPlaces(int totalPlaces){}
    int GetTotalPlaces(){}
    void SetBusyPlaces(int vusyPlaces){}
    int GetBusyPlaces(){}
    void SetStr(int i, string s){}
    ~Schedule();
};
277
26 мая 2011 года
arrjj
1.7K / / 26.01.2011
vecf.at(index).id или vecf[index].id
Почитай справку
66K
26 мая 2011 года
Antosh
18 / / 25.05.2011
Цитата: arrjj
vecf.at(index).id или vecf[index].id


Такое обращение норм работает в методе класса.
Но у меня struct Flight и vector vecf в методе доступа Private и вот таким образом

Цитата: arrjj
vecf.at(index).id или vecf[index].id

я не могу обратиться к элементу структуры в перегруженных операторах << и >>.

277
26 мая 2011 года
arrjj
1.7K / / 26.01.2011
Так вынеси в public oO
Или добавь пару методов класса для работы с элементами вектора.
И где у тебя перегружены операторы <<>>?
66K
26 мая 2011 года
Antosh
18 / / 25.05.2011
Так в public выносить не интересно), да и нужно в private чтобы было.
операторы перегружены в отдельном файле в котором и определен код всех методов класса Schedule (файл schedule.cpp).
вот пример перегрузки оператора >> (код не весь, тут он обрабатывает строку из файла и должен присваивать элементам в структуре значения. можно конечно тут описать написать vecf.push_back(Flight(значения)); но все равно нужно как-то реализовать изменение отдельных элементов структуры) :
 
Код:
ifstream& operator >> (ifstream& stream, vector& vecf)
{
    vecf[0].day=12;
}

так не прокатывает. и еще как мне передавать сюда вместо 0 изменяемый индекс i ?
на счет создать пару методов для работы с вектором, я как-то не совсем понимаю что именно в этих методах описать :confused:
316
26 мая 2011 года
Alm3n
889 / / 29.05.2009
Цитата: Alexander92
Вообще, личный совет: старайтесь для практически любого класса (в пределах разумного, конечно) создавать конструктор по умолчанию


таки VC его по дефолту не делает что ли? должен же компилятором создаваться, если оного нет.

66K
26 мая 2011 года
Antosh
18 / / 25.05.2011
Цитата: Alm3n
таки VC его по дефолту не делает что ли? должен же компилятором создаваться, если оного нет.



так он создается по умолчанию компилятором, но иногда нет, в данном случае был создан конструктор с параметрами и уже автоматов пустой конструктор не создавался компилятором пока я его не описал руками

278
26 мая 2011 года
Alexander92
1.1K / / 04.08.2008
Цитата: Alm3n
таки VC его по дефолту не делает что ли? должен же компилятором создаваться, если оного нет.



Конструктор по умолчанию создается только если не указан никакой другой. Я еще раз подчеркиваю - это не требование, а совет, дабы не напарываться на глупые ошибки.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог