Прочитать файл данных, содержащий объекты 2 разн. классы

0

Я пишу программу для управления запасными деталями книжного магазина. Он продает как книги, так и их аудиокассетные версии. Мои определенные классы:

class stock

{
char title[30],author[15];
float price; int stockpos;
char version[5];

protected:

void getdata(); void putdata();
void defvers(char a[])  {strcpy(version,a);}//used to identify book & tape
void rettitle(char a[]) {strcpy(a,title);}
void retauthor(char a[]){strcpy(a,author);}
void retvers(char a[])  {strcpy(a,version);}/* all these used to obtain title, 
author, and whether its a book/tape to compare with the given details while searching*/

};

Здесь я определил класс для общих членов данных и функций и вывел 2 книги и ленту для определения уникальных членов данных.

class book:public stock

{
int pagecount;

public:
book()   {  pagecount=0; defvers("book");    } //ctor
void getdata();
void putdata();

};

class tape:public stock

{
float duration; char readby[15];
public:
tape()    {  duration=0.00; defvers("tape");  }//ctor
void getdata();
void putdata();

};

Я использую один файл данных stock.dat и сохраняю информацию о книгах и лентах.

Теперь, что меня насторожило, как определить функцию класса на складе, которая будет отображать все детали книг или лент, в зависимости от выбора пользователя, из этого единственного файла данных stock.dat. Увидев, что как классы книг, так и ленты будут иметь разные размеры, как я могу манипулировать файлом file.read()? Или я ошибаюсь и должен просто создать 2 отдельных файла данных books.dat и tapes.dat, не заботясь о том, что он удлинит исходный код?

Пожалуйста, помогите мне здесь. ~ Атхира

edit: Да У меня есть поле для указания, будет ли это книга или лента. его "версия [5]", определенная в классе. Проблемная область для меня заключается в том, что объекты производных классов книги и ленты, которые я использую для записи в двоичные данные, имеют разные размеры.

Содержимое в файле несколько похоже на:

книга (размер x) книга (размер x)

лента (размера y)

книга (размера x)

лента (размера y) (размер y)

Тогда как я могу читать только объекты ленты и отображать их?

РЕДАКТИРОВАТЬ:
Спасибо, Alwin, Pita и Retired Ninja за ответы на мои вопросы. Ваш вклад был очень ценным для меня. Я изучил вещи и получил много идей о том, как создать свой проект. Я искренне благодарен вам за то, что вы нашли время, чтобы помочь мне и терпеливо ответить на мои вопросы. Еще раз, спасибо всем.

  • 0
    Ваш файл в текстовом или двоичном формате? В любом случае вы можете сохранить тип объекта, который будет прочитан следующим, а затем обработать его соответствующим образом.
  • 0
    Вопрос обновлен. Пожалуйста, проверьте это.
Показать ещё 3 комментария
Теги:

3 ответа

0

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

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

Вы найдете следующую запись, перемещая указатель запаса вперед по размеру вашего производного класса.

Это очень грубо и никогда не будет стоять в реальных приложениях, но это может сделать для вашего школьного проекта.

В стороне, похоже, вы пишете код C и пытаетесь поместить его в куртку C++. Возможно, вам будет удобнее писать ваше приложение в C с помощью structs. Это может сделать вещи более знакомыми/очевидными для вас.

Удачи.

0

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

Многое зависит от того, как вы организуете свой объект внутри своего приложения. Вы держите объекты в векторах или используете массивы (из-за того, что вы используете char a[] в ваших подписях функций и используете strcpy, я получаю отличное впечатление, что вы C-кодер и, следовательно, используете массивы). Вы используете несколько массивов или один массив?

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

Удачи.

[РЕДАКТИРОВАТЬ]

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

Так что либо это упражнение, либо вы ошибаетесь. Не изобретайте велосипед и не используйте то, что там. Учитывая то, что вы сказали мне до сих пор, я понимаю, что эта база данных приложений будет небольшой и работает в условиях низкой нагрузки. Вы также указали, что хотите, чтобы ваши данные хранились в одном файле.

Я предлагаю вам изучить SQLite, свободную систему доступа к базе данных. Вы можете получить его с исходным кодом, чтобы узнать и включить в свою программу.

Удачи

  • 0
    Я использую массивы для получения пользовательских вариантов, таких как «книга», «лента», а также извлекаю такие вещи, как автор, для сравнения во время поиска Например, retauthor () будет копировать имя автора, хранящегося в читаемом объекте, в строку rauthor, чтобы я мог сделать «если rauthor текущего прочитанного объекта равен sauthor, заданному пользователем, то отобразить этот объект».
  • 0
    Я сделал книги и кассеты отдельными классами, потому что лента / аудиокнига была бы задана минутами и озвучена кем-то, что неприменимо к книгам. Точно так же у аудиокниги не было бы никакой. страниц, которые книга как. Если бы я сделал один класс, представляющий как книги, так и ленты, то для одного вида некоторые поля пришлось бы оставить пустыми, что я не уверен, разрешено ли это.
Показать ещё 6 комментариев
0

Если вы настаиваете на том, чтобы поместить данные в 1 файл, вероятно, было бы неплохо добавить поле к вашим данным, называемое "тип", который идентифицирует, какие данные хранятся в этом объекте.

но я определенно рекомендую поместить его в два разных файла, так как это упростит многие вещи, а также сделает код более удобным.

и почему вы не используете никаких возвратов, если это C++?

  • 0
    Вопрос обновлен. Пожалуйста, проверьте это.
  • 0
    Я согласен с Элвином Лерингом в том, что вы пытаетесь написать низкоуровневый код базы данных, что нелегко сделать. С бинарными файлами вы не можете делать что-то вроде getLine() читайте здесь. C-faq.com/stdio/textvsbinary.html просто любопытно, это школьный проект? Я определенно рекомендую использовать обычный csv-файл вместо двоичного для таких операций или использовать SQLite.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню