You are here:

C++/ofstream and setf

Advertisement


Question

hello

i have the following question for you

i want to change the flags of a ofstream variable
for example

ofstream writebinary;
writebinary.open("text.txt");
writebinary.setf(ios::binary | ios::app);

but when i compile the program it says that there is
no matching function for setf()

how can i change the flag of a ofstream variable

thanks

Answer
That is because there is not. Or possibly there is not.

The std::ios_base::setf functions take parameters of type std::ios_base::fmtflags not std::ios_base::openmode, which are the flag types you are trying to use with setf.

Note: The derivation graph for std::ofstream is as follows:

std::ios_base<---std::basic_ios<><---std::basic_ostream<><---std::basic_ofstream<>

Where: B<---D  means B is a base class of D (or D is derived from B)

std::ofstream is a specialisation of the std::basic_ofstream<> class template for narrow char based streams.

Likewise std::ios is a specialisation of the basic_ios<> class template for narrow char based streams.

The std::ios_base::fmtflags and std::ios_base::openmode types are typedef type aliases to integer types (the ISO standard C++ document calls them "bitmask types") and so could possibly be aliases to the same type (e.g. unsigned int) but not necessarily. For example on a typical compiler for 32-bit systems std::ios_base::fmtflags could be an alias for unsigned int and std::ios_base::openmode an alias for unsigned char as there are (in the ISO C++ standard) 18 defined format flag values and only 6 open mode values, viz:

   namespace std
   {
       class ios_base
       {
       public:

       // ...

           typedef T1 fmtflags;
           static const fmtflags boolalpha;
           static const fmtflags dec;
           static const fmtflags fixed;
           static const fmtflags hex;
           static const fmtflags internal;
           static const fmtflags left;
           static const fmtflags oct;
           static const fmtflags right;
           static const fmtflags scientific;
           static const fmtflags showbase;
           static const fmtflags showpoint;
           static const fmtflags showpos;
           static const fmtflags skipws;
           static const fmtflags unitbuf;
           static const fmtflags uppercase;
           static const fmtflags adjustfield;
           static const fmtflags basefield;
           static const fmtflags floatfield;

       // ...

           typedef T3 openmode;
           static const openmode app;
           static const openmode ate;
           static const openmode binary;
           static const openmode in;
           static const openmode out;
           static const openmode trunc;

       // ...

           fmtflags flags() const;
           fmtflags flags(fmtflags fmtfl);
           fmtflags setf(fmtflags fmtfl);
           fmtflags setf(fmtflags fmtfl, fmtflags mask);
           void unsetf(fmtflags mask);

       // ...

       };
   }
   
The above is taken from the 1998-09-01 ISO/IEC 14882 C++ standard document and shows _just_ the relevant parts of the std::ios_base base class definition. Note that the exact types of T1 and T3 that std::ios_base::fmtflags and std::ios_base::openmode are aliases for are _not_ specified; it is left up to each implementation to use suitable types.

The reason you cannot change the open mode of the file stream is that these mode flags apply to how the file is _opened_. Hence once opened that is how you have to use the stream with the file. You cannot just change a flag and get read and well as or instead of write access to a file. A file will either be truncated or will not as part of opening the file - adding a flag to alter this behaviour after the request to open would be some what after the fact.

I can see however that the case for specifying whether to perform end of line translation or not (as controlled by the binary open mode flag) only at file open time could be seen as a little more tenuous. However as a file will generally either be processed as text (i.e. lines, using native end of line character sequences), or as just a sequence of bytes (i.e. binary) then again it makes sense to specify it up front when opening the file.

Note also that the ios::binary flag has no effect on systems such as UNIX and Linux where the end of line character sequence is the same as that used by C and C++ - i.e. just a newline ('\n') character.

If you wish to specify the open mode flags then you do it by passing a second parameter with the required open mode flags bits set after the file pathname value either in the relevant constructor or in a call to open:

   ofstream writebinary("text.txt", ios::binary | ios::app);

or:

    ofstream writebinary;

    writebinary.open("text.txt", ios::binary | ios::app);

I suggest you get yourself a decent reference on C++ IOStreams. For the whole of the C++ standard library and not just the IOStream library I use "The C++ Standard Library A Tutorial and Reference" by Nicolai M. Josuttis. For more focus on C++ IOStreams and locales I use "Standard C++ IOStreams and Locales" by Angelika Langer and Klaus Kreft.

Hope this helps.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2012 About.com, a part of The New York Times Company. All rights reserved.