| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Глюки с записья файла |
| Автор: Xenon 16.12.2006, 22:47 | ||
| И опять какие-то глюки. Я fstream file вынес и сделал полем класса Cmanager и в методе save(). Теперь у меня выкидывается исключение, мол файл не существует. Если я убираю if(!file) { throw "Couldn`t open file" то цикл нормально крутится, файл создается, но размером 0 байт. Если же в save вручную ввести локальную переменную ofstream file2 и везде вместо file там испольлзовать file2, то все работает. Ошибка, вероятно, глупая. Я ее не вижу И вообще save_as() вызывающий save() у меня сделано нормально, или так не делают?
И как лучше реализовать проверку "Если файл открыт, ты при вызове save() просто сохранить файл, а если нет, то вызвать save_as() для введения пути к файлу"? Проверять в save условие if (!file.is_open()) { save_as(); }. Ну, естественно, из метода open() надо будет выкинуть file.close()". |
| Автор: zkv 17.12.2006, 04:13 |
| Xenon, можно уточнить вопрос? т.е. привести участок кода, где возникает ошибка, и все что может быть с ней связано - создание объекта класса, инициализация членов и т.д. А то кода много, копаться лень |
| Автор: Rockie 17.12.2006, 04:42 |
| Xenon, если честно, не очень понятна логика.. По мне так - сделать массив path динамическим и в кострукторе занулять его. Тогда в методе Save(): Если в массиве path что-то есть, смотрим, есть ли такой файл - если такой файл есть, дописать туда(или переписать, не знаю что тебе нужно) - если нет такого - спрашиваем, заносим в path название и пишем fstream file лучше создавать в методе, это обеспечит закрытие файла при выходе из метода(ИМХО). |
| Автор: Xenon 17.12.2006, 14:24 | ||||||||||||
| Ну я вроде нормально написал где проблема в каком методе ... Ок, немного поподробнее Проблема возникают тут, но где она родилась - не знаю.
Как видите у меня в методе save() имеется условие:
Сейчас в независимости от того, какой путь, у меня всегда выкидывается исключение "Couldn`t open path". Если же вышеприведенный участок закомментировать, а в цикл добавить вывод состояния счетчика, то мы увидим, что цикл работает.
Если у меня 3 альбома в album_list, то на экране появятся цифры "0,1,2". Создается файл, но он размером в 0 байт. Если же сделать так:
То все работает ну просто зашибись - и цикл крутится и файл создается. Я поэтому и не понимаю, чего плохого в том, что file у меня торчит в виде поля класса и если это нормально, то где с ним что в коде приключается Rockie, А я так сделал только потому, что мне необходимо считывать пути с пробелами ... cin.getline() же требует char*. Ты предлагаешь объявить переменную char* path, затем в save_as() и open() добавить
Так ? А что ты подрузомеваешь под обнулением?
Ну гарантирует, я не спорю, но просто я решил то, к чему я часто обращаюсь и что часто создаю вынести и сделать общим - сэкономил несколько строчек кода |
| Автор: Anikmar 17.12.2006, 14:50 | ||
Мне кажется, что если file объявлен как поле класса он может неправильно проинициализироваться. Попробуй объявить его как указатель, а создавать и уничтожать в конструкторе и деструкторе. |
| Автор: nickless 17.12.2006, 15:52 | ||
У меня вот так нормально работает:
Как ты используешь свой класс? Может там где-нибуть ошибка? Насчет path, или используй string, или хотя бы добавь в конструктор path[0] = 0;, а то если случайно вызвать save() перед save_as(), то всё это дело запишется (если повезёт), куда попало. |
| Автор: Xenon 17.12.2006, 15:57 | ||||
| Anikmar, сделал, как ты сказал, но теперь еще веселее - исключительной ситуации не происходит, но файл размером 0 байт Добавлено @ 16:00 nickless, вот так.
Некоторых пунктов меню не выводится, но это я просто пока не успел их закинуть, но из кода видно, чего нажимать надо Компилятор VC++ 2005 А как ты предлагаешь в string считывать поток без пробелов с возможностю корректирования, как в cin? Разве что:
Но это же жуть ... |
| Автор: nickless 17.12.2006, 16:17 | ||||||
Странно, вроде ничего такого... а ты добавляешь хотябы один альбом? В коде этого нет. Попробуй еще просто добавить альбом и сразу сохранить, как в моём коде.
В string есть такая глобальная функция:
Т.е. примерно так:
|
| Автор: Xenon 17.12.2006, 16:29 |
| nickless, о, клево, не знал А я пробовал просто добавить альбом и сохранить - нифига. Пробовал заимпортить и сохранить - нифига. Добавить или заимпортить из txt и экспортировать в txt - тоже файл размером 0 байт. |
| Автор: Xenon 17.12.2006, 17:28 |
| nickless, попробовал сделать как ты (я про main.cpp) - работает ... |
| Автор: nickless 17.12.2006, 17:34 |
| Может VC глючит? Попробуй чем-нибудь другим скомпилить, или file.flush() в деструкторе написать. Проверь еще, какой статус у file.fail(), file.bad() и file.good(). edit Может ты как-то умудряешся выйти из main() не вызвав деструктора? |
| Автор: Xenon 17.12.2006, 17:54 |
| nickless, а как невызов деструктора вляиет на невозможность считать? Еще интересен тот факт, что созданный файл размером 0 байт нельзя убить, пока программа работает - говорит занят файл. Еще интересно - нажимаешь p (сохранить файл), мне сразу говорит, что путь неверен. Нажимаешь еще один раз - предлагает ввести. Если импортируешь из txt альбомы, а не просто добавляешь, то при нажатии p все нормально - выкидывается "Enter path to file", но дальше тоже самое - couldn`t open file и файл с 0 байт. Поменя char path[256] на string - никаких эмоций. |
| Автор: nickless 17.12.2006, 18:12 | ||||||
Я просто подумал, может fstream не пишет в файл если деструктор не вызывался, но вообще после close() это не должно мешать...
А если нормально выключить программу, потом сделать рефреш в експлорере и потом еще раз посмотреть на размер файла?
Посмотри что находится в path в первый раз |
| Автор: Xenon 17.12.2006, 18:32 | ||
| nickless, не-а, 0 байт и хоть ты здохни. Если просто добавлять альбомы, а затем сохранять, то как и положено - сначало пусто, а потом тот путь, что указан при вводе. При использовании локально созданного file все работает ... Ну пипец ... Крыша, не уезжай
|
| Автор: zkv 17.12.2006, 20:48 | ||||
| не знаю, насколько верно я понял проблему, но в вашей программе я увидел две проблемы: 1. когда пользуемся getline() туда иногда лезет мусор, попробуйте так:
2. как вам уже говорили fstream file; у вас член класса, когда прога натыкается на eof() устанавливаются "плохие" биты состояния (или биты плохого состояния
но это так, первое, что под руку попало, а конкретного вопроса я так и не разглядел, простите... PS вы про пошаговое выполнение программы не слышали? |
| Автор: Xenon 17.12.2006, 21:05 |
| zkv, _flushall(); все исправил! Спасибо! Но какая связь между fstream file объявленным как поле и как локальная переменная и буфером? |
| Автор: Xenon 17.12.2006, 21:24 |
| zkv, э-э-э, не понял ... Я могу создать альбомы не путем открывания файла, а просто добавлением (fstream никак тут не участвует). То есть биты состояния никак не изменяются до того, как я вызываю save_as() (если я обращаюсь даже к переменной file, то как они изменятся)? В любом случае ошибка таже самая Помог именно flushall(), а не сброс битов. Или это и есть есть сброс битов? Если да, то где в программе биты ошибок изменились, если я не открывал файла? |
| Автор: zkv 17.12.2006, 21:29 |
| попробуй запустить свой пример (уже с учетом _flushall(), но без file.clear() ), экпортируй альбомы в текстовый файл, а потом импортируй из него альбомы в первый раз все ок будет, а во второй получишь по рукам повторюсь, я не понял конкретно вопроса, по этому просто запустил твою прогу и посмотрел, что там не так работает, возможно ты еще не натолкнулся на эту ошибку |
| Автор: Xenon 17.12.2006, 22:07 |
| zkv, импортируется нормально, а на экспорте уже по рукам дадут. Я говорю - все, что связано С ЗАПИСЬЮ не функционировало как надо |