как мога законно да променя стойността на името на файла на обекта 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