Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Дублирование записи при выводе файла 
:(
    Опции темы
admin82
Дата 22.8.2006, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 22.8.2006

Репутация: нет
Всего: 1



Всем добрый! Пробую тут после Delphi осилить С++ (в VC2005), и вот первая проблема:
Код

void VyvodFile(fstream& Base)
{
   int t;
   Abonent abonent;
   long n = 0;
   cout<<"Vasha baza: "<<endl;
   cout<<setiosflags(ios::left)<<setw(20)<<"FIO"<<setw(15)<<"Adress"<<setw(11)<<"Telefon"<<endl<<endl;
   while (!Base.eof())
   {
      Base.seekg(n);
      Base.read((char*)&abonent,sizeof(Abonent));
cout<<setiosflags(ios::left)<<setw(20)<<abonent.FIO<<setw(15)<<abonent.adress<<setw(11)<<abonent.tel<<endl;
      n+=sizeof(Abonent);
   }
   Base.clear();
}


Перед этим файл Base открыт так:
Код

fstream Base("base.dat",ios::in|ios::out);
   if (!Base)
   {
      cerr<<"The file can't be opened!"<<endl;
      exit(1);
   }


Abonent -- структура, соответственно, и файл состоит из записей такого типа.
Функция void VyvodFile(fstream& Base) должна всего лишь его вывести на экран. Так вот, последняя запись файла выводится на экран дважды, и ничего с этим поделать не могу. Ваши предположения?

И еще. Ввод новых записей и редактирование я сделал, а как удалить запись из файла?

Это сообщение отредактировал(а) admin82 - 22.8.2006, 13:29
PM MAIL   Вверх
Earnest
Дата 22.8.2006, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Читать нужно не до eof, а до того момента, как read вернет 0.
Нужно иметь в виду, что состояние eof возникает не тогда, когда позиция чтения достигает конца файла, а когда делается попытка читать за концом файла.
Таким образом, последняя итерация возвращает 0 байтов, буфер не перезаписывается, и ты еще раз выводишь строку.
Нужно так:
Код

while (Base.read((char*)&abonent,sizeof(Abonent)) != 0)
{
      cout<<setiosflags(ios::left)<<setw(20)<<abonent.FIO<<setw(15)<<abonent.adress<<setw(11)<<abonent.tel<<endl;
}



--------------------
...
PM   Вверх
admin82
Дата 22.8.2006, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 22.8.2006

Репутация: нет
Всего: 1



Супер, спасибо!!!!!!
Только надо еще в теле цикла писать 

Код

n+=sizeof(Abonent);


А как удалить запись из файла? Является ли приемлимым решение очистить значение всех полей? Видимо нет, так как запись останется существовать....

Это сообщение отредактировал(а) admin82 - 22.8.2006, 14:48
PM MAIL   Вверх
Earnest
Дата 22.8.2006, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(admin82 @  22.8.2006,  15:46 Найти цитируемый пост)
Только надо еще в теле цикла писать 

Для чтения - не надо.

Цитата(admin82 @  22.8.2006,  15:46 Найти цитируемый пост)
А как удалить запись из файла? Является ли приемлимым решение очистить значение всех полей? Видимо нет, так как запись останется существовать....

Удалить - значит переместить все последующие записи вперед. Очевидно, для файла это неприемлимо.
Проще всего ввести a запись флаг и помечать удаленные записи.
Иногда - упаковывать, т.е. переписывать из старого файла в новый, только непомеченные записи.



--------------------
...
PM   Вверх
admin82
Дата 23.8.2006, 08:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 22.8.2006

Репутация: нет
Всего: 1



А почему неприемлимо? 
PM MAIL   Вверх
Earnest
Дата 23.8.2006, 08:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Потому что для этого придется перезаписывать весь файл.


--------------------
...
PM   Вверх
admin82
Дата 23.8.2006, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 22.8.2006

Репутация: нет
Всего: 1



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

Это сообщение отредактировал(а) admin82 - 23.8.2006, 09:15
PM MAIL   Вверх
albertn
Дата 23.8.2006, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 368
Регистрация: 17.7.2006
Где: г. Ставрополь

Репутация: нет
Всего: 34



Цитата(admin82 @ 23.8.2006,  09:12)
В Паскале такое возможно...

Паскаль испоьзует почти теже функции, что и си, но в паскале я такого не видел. Приведи пример на паскале как это сделать, или хотя-бы название функции
PM WWW ICQ   Вверх
MAKCim
Дата 23.8.2006, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

Не верю, что просто нельзя сфокусироваться на определенной записи и удалить ее

Ну допустим ты заполнил нулями определенное количество байт, которые соответствуют структуре
но размер файла у тебя останется прежним
Можно просто сдвинуть на место удаляемой записи все остальные и образовавшееся место в конце файла заполнить нулями
тогда при чтении нужно кроме того будет проверять, не прочитали ли мы одни нули, если да то дальше можно не читать. Однако при таком подходе иногда могут быть неприятности (чтение последовательности 0-вых байт в общем случае не есть признак конца)


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Earnest
Дата 23.8.2006, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(MAKCim @  23.8.2006,  10:55 Найти цитируемый пост)
Можно просто сдвинуть на место удаляемой записи все остальные 

Это как? Речь-то идет о файле. Фактически получается полное переписывание файла (для начальных записей).

Цитата(admin82 @  23.8.2006,  10:12 Найти цитируемый пост)
 это все равно не выход

Вот разработчики DBF так не считали. 
Кто будет упаковывать - твой код, конечно, время от времени или по команде. Дело-то не сложное, просто относительно долгое, поэтому использовать для оперативного удаления нельзя.



--------------------
...
PM   Вверх
admin82
Дата 23.8.2006, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 22.8.2006

Репутация: нет
Всего: 1



Нет у меня сейчас делфы по рукой, как не искал. Но года два назад писал программу для тестирования учащихся, и вот там вопросы с вариантами ответов находились в типизированном файле. Эти файлы можно было создавать в одном из режимов программы для новых тем. И можно было редактировать. Хоть убей, не помню, как я это делал, но и не припоминаю, чтобы у меня это вызвало тогда затруднения.
PM MAIL   Вверх
Earnest
Дата 23.8.2006, 18:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



И можешь дать 100% гарантию, что там не было пометки записей? Просто Дельфи заточен на работу с БД и многое делает сам, тебя не спрашивая.
При этом не исключен вариант и с физическим удалением записи (т.е. уплотнением файла при каждом удалении). При небольших размерах файла ты бы этого не заметил. А может, все записи в память считывались и редактировались там.



--------------------
...
PM   Вверх
MAKCim
Дата 23.8.2006, 19:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

Это как?

с помощью
tellp, seekp, read, write
Цитата

Речь-то идет о файле. Фактически получается полное переписывание файла (для начальных записей).

так и получается


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
admin82
Дата 24.8.2006, 08:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 22.8.2006

Репутация: нет
Всего: 1



Цитата

И можешь дать 100% гарантию, что там не было пометки записей? Просто Дельфи заточен на работу с БД и многое делает сам, тебя не спрашивая.
При этом не исключен вариант и с физическим удалением записи (т.е. уплотнением файла при каждом удалении). При небольших размерах файла ты бы этого не заметил.

Могу. Программу то я писал, и что такого не делел, помню наверняка. На автомате вельфи бы ничего с файлом не сделал, это все же не БД была. 
Цитата

А может, все записи в память считывались и редактировались там.

А вот это более вероятно. Может, и так. 

Ну а если подвести итог, то всем спасибо за участие. С удалением что-нибудь уже придумаю. Приятно было  получить столько ответов.  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1138 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.