как законно изменить значение имени файла объекта ofstream?

У меня проблемы с ofstream , то есть когда я меняю значение объекта ofstream вот так

ofstream o_save; 

/*code*/

o_save = ofstream(filename);  //Problem is here

... строка выше полностью стирает содержимое файла.

Вопрос в том, как законно изменить filename значение ofstream объекта?

P.S. Я не могу определить его, когда объявляю, потому что я хочу, чтобы он был глобальным, и я не уверен, какой файл сохранения выбрать.


person user1849353    schedule 24.11.2012    source источник
comment
Используйте o_save.open("file.txt", ios::app), чтобы открыть, а затем закрыть, используя o_save.close(). После этого откройте еще один.   -  person Coding Mash    schedule 24.11.2012
comment
Простое открытие файла для записи не должно полностью стирать содержимое файла. Он просто открывает файл, чтобы вы сами могли перезаписать его содержимое. Если вы хотите дополнить файл, измените режим открытия.   -  person Some programmer dude    schedule 24.11.2012
comment
Кроме того, вы не можете просто изменить имя файла после его открытия. Похоже, вам нужно немного больше подумать о дизайне нашей программы и о том, чего вы хотите с ее помощью достичь.   -  person Some programmer dude    schedule 24.11.2012
comment
Вопрос непонятен сам по себе. Заголовок говорит об изменении имени файла, а содержание говорит о сохранении содержимого файла. @ user1849353 что именно ты хочешь?   -  person Coding Mash    schedule 24.11.2012
comment
@JoachimPileborg Простое открытие файла для записи приводит к его обрезанию. Можно возразить, что этого не должно быть, но стандарт требует этого.   -  person James Kanze    schedule 24.11.2012
comment
ofsteram объекты не имеют значений имени файла, поэтому вопрос некорректен. Голосование за закрытие.   -  person Yakov Galka    schedule 24.11.2012
comment
@JamesKanze О, хорошо. Но тогда для чего нужен открытый режим trunc?   -  person Some programmer dude    schedule 24.11.2012
comment
Вы действительно не хотите, чтобы это было глобально. Вместо этого вы хотите дать своим функциям сохранения аргумент ostream &.   -  person Kerrek SB    schedule 24.11.2012
comment
@JoachimPileborg Чтобы очистить файл, если вы открываете его как для чтения, так и для записи. Я согласен, что это не очень полезно. И что открытые флаги в целом не очень ортогональны или когерентны --- они предназначены для простого сопоставления с fopen режимами, а не для того, чтобы быть логичными.   -  person James Kanze    schedule 24.11.2012
comment
@JamesKanze Ах да, теперь я вижу таблицу с открытыми режимами и соответствующими им режимами fopen в стандарте. Единственный раз, когда нужны флаги trunc, это для режима "w+" fopen.   -  person Some programmer dude    schedule 24.11.2012


Ответы (3)


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

Для открытия файла существует множество режимов. Откройте его так.

ofstream o_value ;
o_value.open("file.txt") ;

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

o_value.open("file.txt", ios::app) ;

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

o_value.close() ;

Изменение имен файлов обычно не допускается в случае ofstream. Вы можете использовать rename из <cstdlib>. Вы можете удалить файл, используя remove("file.txt") в <cstdio> .

person Coding Mash    schedule 24.11.2012

Что значит «изменить имя» объекта ofstream? Единственное «имя» объекта ofstream — это имя переменной. Объект ofstream представляет собой поток данных. Вы можете (в некоторых системах) изменить имя файла, с которым он связан, используя rename, но почему-то я не думаю, что это то, что вам нужно. Вы также можете закрыть поток и снова открыть его в другом файле.

Вы не можете назначать между объектами iostream. В худшем случае вы можете объявить глобальный объект указателем и присвоить ему значение (используя *o_save для записи в него).

Наконец, стандарт говорит, что когда вы открываете ofstream, вы усекаете файл, если он существует. Если это не то, что вы хотите сделать, вам нужно добавить некоторые флаги в открытый режим. Если вы добавите, например, std::ios_base::app, вы больше не будете усекать файл, и все записи будут выполняться в конец файла (атомарно, если система это поддерживает). В качестве альтернативы (хотя и довольно неожиданной) вы можете добавить std::ios::in к флагам; это не удастся, если файл не существует, но позволит писать в любом месте файла. Это единственный способ открыть файл для записи, если вы хотите иметь возможность писать в любом месте файла, даже если вы не хотите его читать.

person James Kanze    schedule 24.11.2012

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

изменить filename значение ofstream объекта

бессмысленно.

В общем, вы можете переименовывать файлы с std::rename из <cstdlib> или использовать Boost.Filesystem.

person chill    schedule 24.11.2012