Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 51, средняя оценка - 4.88
Teravisor
31 / 31 / 3
Регистрация: 07.08.2011
Сообщений: 89
#1

fstream: открытие на запись - C++

21.08.2011, 14:42. Просмотров 7319. Ответов 12
Метки нет (Все метки)

C++
1
2
3
fstream a("file.txt",ios::out);
a<<"abc\n";
a.close();
Перезаписывает файл полностью даже без флага ios::trunc.

C++
1
2
3
fstream a("file.txt",ios::out|ios::in);
a<<"abc\n";
a.close();
Перезаписывает только первые 4 символа файла, не обрезая файл. Как и должно быть.

Собственно вопрос:
В первом случае так и должно быть? Если да, то как без ios::in открыть файл, чтобы оно его не обрезало?
Во втором случае не будет ли открываться на запись медленнее, чем в первом?

З.Ы. используется студия 2008.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.08.2011, 14:42
Здравствуйте! Я подобрал для вас темы с ответами на вопрос fstream: открытие на запись (C++):

Открытие файла через объекта класса fstream - C++
Есть функция: bool Lr::MakeFile() { string name, fullname; cout &lt;&lt;&quot;Введите имя нового файла:&quot;; cin.sync(); ...

Запись в файл fstream - C++
Вот такой вот код , изобразил я для записи переменной в файл , проблема в том , что компилятор записывает в него не 10 раз L , а ...

Запись в файл fstream - C++
После первого прогона не выводит ничего из файла. void WriteInTheFile(fstream &amp;file_in) { file_in.seekg(0,file_in.end); char str;...

fstream не работает и чтение и запись - C++
Добрый день! Не пойму, почему введение функции getline становится причиной того, что запись в файл не идет. Если getline убрать, то все...

Запись в середину файла - fstream - C++
Как можно при помощи fstream (хотелось бы именно им, потому что он умеет и читать, и писать) записать что-либо в середину файла (или куда...

Запись/чтение структуры через fstream - C++
Доброго времени суток! у меня есть несколько вопросов по поводу файловых потоков. 1. Как можно записать/прочитать массив структур в...

12
diagon
Higher
1933 / 1199 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
21.08.2011, 14:52 #2
Цитата Сообщение от Teravisor Посмотреть сообщение
В первом случае так и должно быть?
да

Цитата Сообщение от Teravisor Посмотреть сообщение
как без ios::in открыть файл, чтобы оно его не обрезало?
C++
1
ios::app
Добавление в конец файла.
1
Teravisor
31 / 31 / 3
Регистрация: 07.08.2011
Сообщений: 89
21.08.2011, 14:57  [ТС] #3
Спасибо за быстрый ответ.
Цитата Сообщение от diagon Посмотреть сообщение
C++
1
ios::app
Добавление в конец файла.
А в случае, если мне надо не дописать в конец, а заменить часть текста? Только ios::in добавлять? Или оно работает не так, как я себе представляю, и все равно не хорошо получится?
(размер файла не меньше мегабайта, а то и 10ти - все переписывать - мне жесткий диск жалко, перезаписей того же размера будет очень много)

И да, если так и должно быть, то зачем нужен ios::trunc?
0
Gepar
1180 / 536 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
21.08.2011, 15:32 #4
Teravisor, открой файл, а потом установи курсор куда тебе нужно чтобы начать дописывать файл используя seekp(позиция). После этого наверное надо будет очистить файл до конца, но это ты уже смори сам что тебе дальше будет нужно сделать.

Цитата Сообщение от Teravisor Посмотреть сообщение
то зачем нужен ios::trunc?
Чтобы "отбросить" содержимое файла.
0
Teravisor
31 / 31 / 3
Регистрация: 07.08.2011
Сообщений: 89
21.08.2011, 16:46  [ТС] #5
Цитата Сообщение от Gepar Посмотреть сообщение
Teravisor, открой файл, а потом установи курсор куда тебе нужно чтобы начать дописывать файл используя seekp(позиция). После этого наверное надо будет очистить файл до конца, но это ты уже смори сам что тебе дальше будет нужно сделать.


Чтобы "отбросить" содержимое файла.
Вы видимо не поняли. Оно "отбрасывает" содержимое даже без флага ios::trunc, если не сообщить ios::in. В этом проблема. Я не понимаю почему, и хотелось бы, чтобы кто-то мне объяснил где я(или на крайний случай fstream) не прав.
0
Gepar
1180 / 536 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
21.08.2011, 17:56 #6
Перед тем как дописывать к файлу информацию сделай так
C++
1
file.seekp(0,ios::end);
Курсор будет гарантированно в конце файла и никаких магических 4х байт (символов) убираться нигде не будет.
0
Teravisor
31 / 31 / 3
Регистрация: 07.08.2011
Сообщений: 89
21.08.2011, 20:03  [ТС] #7
Цитата Сообщение от Gepar Посмотреть сообщение
Перед тем как дописывать к файлу информацию сделай так
C++
1
file.seekp(0,ios::end);
Курсор будет гарантированно в конце файла и никаких магических 4х байт (символов) убираться нигде не будет.
Во-первых это - аналог открытия с флагом ios::app.
Во-вторых, я нигде про 4 байта не говорил. У меня обрезает ВЕСЬ файл как если бы был применен ios::trunc (как я понимаю его действие).
В третьих, я уже сказал, мне надо перезаписать КУСОК файла без копирования его всего, и причина этому - размер файла. Для этого ios::app(и его аналоги) НЕ годятся.
Пожалуйста, когда отвечаете, прочитайте повнимательнее что я хочу, и в чем у меня вопрос, т.к. это не имеет к моим вопросам никакого отношения.

Итак, переформулирую вопросы более конкретно:
1. Почему при открытии только с флагом ios::out оно файл обрезает(т.е. удаляет его содержимое)?
2. В следствие вопроса 1. - зачем нужен ios::trunc, если файл при ios::out оно и без него обрезает?
3. Почему при открытии с флагами ios::out|ios::in не обрезает и как работает перезапись части файла в таком режиме?
4. В следствие вопроса 3. - работает ли перезапись в режиме ios::out|ios::in быстрее, чем полное копирование файла с соответствующими изменениями?
5. Существует ли более быстрый способ заменить часть файла на аналогичную по размеру?
0
kazak
3051 / 2372 / 160
Регистрация: 11.03.2009
Сообщений: 5,438
Завершенные тесты: 1
22.08.2011, 08:38 #8
Для произвольного доступа есть режим ios::ate.
0
Gepar
1180 / 536 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
22.08.2011, 14:03 #9
Цитата Сообщение от Teravisor Посмотреть сообщение
мне надо перезаписать КУСОК файла без копирования его всего
ну да, учитесь читать что вам уже написали:
Цитата Сообщение от Gepar Посмотреть сообщение
открой файл, а потом установи курсор куда тебе нужно чтобы начать дописывать файл используя seekp(позиция).
Информация которая будет после того что вы дописывали останется и никуда не денется.
Пример с мнемокодом:
file:123456789
file.seekp(3)
file<<бла
file:123бла789

Сделав так никуда ничто не будет отбрасываться, только это надо попробовать прежде чем задавать 100500ый раз тот же вопрос.

Цитата Сообщение от Teravisor Посмотреть сообщение
1. Почему при открытии только с флагом ios::out оно файл обрезает(т.е. удаляет его содержимое)?
Потому что файл открывается для ВЫВОДА.
Цитата Сообщение от Teravisor Посмотреть сообщение
2. В следствие вопроса 1. - зачем нужен ios::trunc, если файл при ios::out оно и без него обрезает?
Потому что гладиолус отбрасывается содержимое файла, никто нигде никому обрезаний не делает.
Цитата Сообщение от Teravisor Посмотреть сообщение
3. Почему при открытии с флагами ios::out|ios::in не обрезает и как работает перезапись части файла в таком режиме?
Потому что файл открывается и для ВВОДА и для ВЫВОДА, смысл открывать для ВВОДА с файла пустой файл (если отбросить его содержимое?).

Цитата Сообщение от Teravisor Посмотреть сообщение
4. В следствие вопроса 3. - работает ли перезапись в режиме ios::out|ios::in быстрее, чем полное копирование файла с соответствующими изменениями?
Быстрее чем что? Чем создание нового файла и запись его с нуля полностью? Ну конечно работает быстрее. Проще открыть файл размером в 1 гб для чтения и записи и изменив 1 байт закрыть его чем перезаписать новый изменённый файл.
Цитата Сообщение от Teravisor Посмотреть сообщение
5. Существует ли более быстрый способ заменить часть файла на аналогичную по размеру?
Интересно каким образом не открывая файл для вывода вы собрались заменить его часть, разве что ваш винт может быстро заменить содержимое битыми секторами и это и впрямь будет быстрее чем вы будете редактировать файл.
А вообще все 5 вопросов описаны же в книге, я считаю что все ваши 5 вопросов вы могли и сами решить прочитав соотв. главу в учебнике по с++.
0
Teravisor
31 / 31 / 3
Регистрация: 07.08.2011
Сообщений: 89
22.08.2011, 15:42  [ТС] #10
Конечно, спасибо за ответы, НО:
Цитата Сообщение от kazak Посмотреть сообщение
Для произвольного доступа есть режим ios::ate.
"ios::ate Set the initial position at the end of the file.
If this flag is not set to any value, the initial position is the beginning of the file."
См. то, что мне нужно.

Цитата Сообщение от Gepar Посмотреть сообщение
Teravisor, открой файл, а потом установи курсор куда тебе нужно чтобы начать дописывать файл используя seekp(позиция). После этого наверное надо будет очистить файл до конца, но это ты уже смори сам что тебе дальше будет нужно сделать.
Цитата Сообщение от Gepar Посмотреть сообщение
Информация которая будет после того что вы дописывали останется и никуда не денется.
Пример с мнемокодом:
file:123456789
file.seekp(3)
file<<бла
file:123бла789
Сделав так никуда ничто не будет отбрасываться, только это надо попробовать прежде чем задавать 100500ый раз тот же вопрос.
Извините, но я ПРОБОВАЛ, и всё зависит от того как вы файл откроете. ios::out? тогда содержимое выкинется. и получится результат
file:бла
ios::in|ios::out? а зачем нам ios::in, мы не собираемся читать, только записывать?


Цитата Сообщение от Gepar Посмотреть сообщение
Потому что файл открывается для ВЫВОДА.
ios::out|ios::in не поверите, ТОЖЕ открывает файл для ВЫВОДА! Но еще и для ВВОДА, что мне совершенно не нужно в данном случае. Вопрос прочитайте по внимательнее - я же спрашиваю почему оно выкидывает содержимое файла даже без ios::trunc

Цитата Сообщение от Gepar Посмотреть сообщение
Потому что гладиолус отбрасывается содержимое файла, никто нигде никому обрезаний не делает.
Повторю в третий раз: И без него оно выбрасывает содержимое.

Цитата Сообщение от Gepar Посмотреть сообщение
Потому что файл открывается и для ВВОДА и для ВЫВОДА, смысл открывать для ВВОДА с файла пустой файл (если отбросить его содержимое?).
Так почему при открытии только на вывод содержимое файла выкидывается?

Цитата Сообщение от Gepar Посмотреть сообщение
Быстрее чем что? Чем создание нового файла и запись его с нуля полностью? Ну конечно работает быстрее. Проще открыть файл размером в 1 гб для чтения и записи и изменив 1 байт закрыть его чем перезаписать новый изменённый файл.
А вдруг оно всю перезапись прячет от пользователя? Вопрос на устройство STL был. Плюс, 1 байт изменить в файле нельзя - минимальная единица изменения - размер кластера на разделе(за исключением особых разделов, которые я не рассматриваю).

Цитата Сообщение от Gepar Посмотреть сообщение
Интересно каким образом не открывая файл для вывода вы собрались заменить его часть, разве что ваш винт может быстро заменить содержимое битыми секторами и это и впрямь будет быстрее чем вы будете редактировать файл.
Я имел ввиду открывая и записывая другими средствами.
Цитата Сообщение от Gepar Посмотреть сообщение
А вообще все 5 вопросов описаны же в книге, я считаю что все ваши 5 вопросов вы могли и сами решить прочитав соотв. главу в учебнике по с++.
Страуструп по этому поводу говорит печальные вещи, в MSDN этот момент не оговорен, на cplusplus.com/doc/ так же нет ответа.

Конкретнее, Страуструп пишет:
Фактические значения openmode и их смысл определяются при реализации. Насчет деталей сверьтесь, пожалуйста, с руководством по вашей системе - и поэкспериментируйте.
Но в MSDN этого не указано. А на эксперименте ios::out без аргументов это то же, что и ios::out|ios::trunc.

Вопрос остается в силе - как заменить часть файла не открывая его на чтение, и насколько менее эффективна работа в режиме ios::out|ios::in, чем просто ios::out. Ни на то, ни на другое я внятного ответа еще не увидел.
0
kazak
3051 / 2372 / 160
Регистрация: 11.03.2009
Сообщений: 5,438
Завершенные тесты: 1
22.08.2011, 16:19 #11
Цитата Сообщение от Teravisor Посмотреть сообщение
"ios::ate Set the initial position at the end of the file.
If this flag is not set to any value, the initial position is the beginning of the file."
Это всего лишь означает, что указатель при открытии файла будет установлен в конец файла. Но его легко можено переместь на любую другую позицию с помощью seekp(), в отличии от режима app при котором запись в файл производиться всегда в конец файла, независимо от текущего положения указателя.
Цитата Сообщение от Teravisor Посмотреть сообщение
Страуструп по этому поводу говорит печальные вещи, в MSDN этот момент не оговорен, на cplusplus.com/doc/ так же нет ответа.
Честно признаться, в официальной справке я тоже этого момента не нашел, но в учебниках оговорки есть, что
Цитата Сообщение от Teravisor Посмотреть сообщение
ios::out без аргументов это то же, что и ios::out|ios::trunc.
, а trunc скорее всего используется в такой конструкции ios::out|ios::in|ios::trunc.
Цитата Сообщение от Teravisor Посмотреть сообщение
Плюс, 1 байт изменить в файле нельзя - минимальная единица изменения - размер кластера на разделе(за исключением особых разделов, которые я не рассматриваю).
Вообще при работе с файлом, он загружается в оперативную память и вся работа с ним происходит в памяти. На диск результат попадает в двух случаях: при закрытии файла функцией close(), и при сбросе буфера функцией fflush() или помещением в поток манипулятора endl. И изменять можно и 1 байт.
1
Teravisor
31 / 31 / 3
Регистрация: 07.08.2011
Сообщений: 89
22.08.2011, 16:21  [ТС] #12
Цитата Сообщение от kazak Посмотреть сообщение
Честно признаться, в официальной справке я тоже этого момента не нашел, но в учебниках оговорки есть, что
А конкретнее, каких учебниках?
0
kazak
3051 / 2372 / 160
Регистрация: 11.03.2009
Сообщений: 5,438
Завершенные тесты: 1
22.08.2011, 16:25 #13
Дейтел, "Как программировать на С++"
1
22.08.2011, 16:25
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.08.2011, 16:25
Привет! Вот еще темы с ответами:

Запись/чтение структур (файлы) + разница между FILE * и <fstream> - C++
Всем привет. Порыскал по форуму, погуглил... Решения есть, но они не ясны (что, почему да как) и не все работают. Однако, я так и не нашёл...

Открытие и запись bmp-файла - C++
Здравствуйте уважаемые участники форума. Прошу помощи, т.к. не могу найти ошибку в программе. Задача - прочитать побайтно файл bmp и...

Открытие и запись файла bmp. Что здесь не так ? - C++
Имеется программа, копирующая содержимое из указанного bmp в файл result. Проблема: файл stars копируется нормально, а вместо...

Создание/открытие файлов, чтение из файла и запись в файл через наследование - C++
Имеется следующая иерархия классов: Файл, Типизированный файл, Текстовый файл Методы: Создать/Открыть файл, Чение из файла, Запись в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru