Sunday, December 1, 2024

basic_ios

Overview
basic_ios is a base class that defines member types and maintains data for classes that inherit from it.

Details
The class basic_ios is a base class that includes the common character-dependent functionality and data members required by all streams. It maintains state information that reflects the integrity of the stream and stream buffer. It also maintains the link between the stream classes and the stream buffer classes via the rdbuf() member functions. Classes derived from basic_ios specialize operations for input and output.

Syntax
template<class CharT, class Traits = char_traits<CharT>> 
class basic_ios: public ios_base
where CharT can be char or wchar_t. It's derived from basic_ios class.

Constructor
NameDescription
basic_ios()Constructs an object of class basic_ios, leaving its member objects uninitialized. The object must be initialized by calling the init() member function before using it.
basic_ios
(basic_streambuf* sb)
Constructs an object of class basic_ios, assigning initial values to its member objects by calling init(sb). If sb is a null pointer, the stream is placed in error state by setting its badbit.
Example
   /*prints
    hello
    */
    ostream os(cout.rdbuf());
    os << "hello";

member types
Following properties are defined. 
NameDefinition
char_typechar/wchar_t
traits_typechar_traits<char_type>
int_typechar_traits<char_type>::int_type
pos_typechar_traits<char_type>::pos_type
off_typechar_traits<char_type>::off_type

Stream State management and error handling
After each IO operation, the state of the stream is returned by stream member iostate. These are defined in ios_base class.

To check for errors,  the following functions and overloaded operators are provided to check of for errors.
NameDescription
bool good()Returns true if all is fine. Otherwise false. Note that is checks all the flags.
bool eof()Returns true if eofbit set as end of the stream is reached. Otherwise false.
bool fail()Returns true if previous operation failed. Example parsing error or file not found Otherwise false. Note that this checks if only failbit or badbit is set. eofbit is not checked.
Example
istringstream ssin("10 20");
    int a;

    //a:10
    ssin >> a;
    //good:true
    auto b = ssin.good();
    //eof:false
    b = ssin.eof();
    //fail:false
    b = ssin.fail();
    //bad:false
    b = ssin.bad();

    //a:20
    ssin >> a;
    //good:false
    auto b = ssin.good();
    //eof:true
    b = ssin.eof();
    //fail:false
    b = ssin.fail();
    //bad:false
    b = ssin.bad();

    ssin.clear();
    
    //a:??
    ssin >> a;
    //good:false
    auto b = ssin.good();
    //eof:true
    b = ssin.eof();
    //fail:true
    b = ssin.fail();
    //bad:false
    b = ssin.bad();
bool bad()Returns true if fatal error occurred during previous operation. Otherwise false.

Example
    ios fs(nullptr);

    //prints true
    cout << fs.bad();
bool operator!()Internally returns fail().

Example
    istringstream ssin("10");
    int a;

    //a:10
    //prints ok
    ssin >> a;
    if (!ssin)
        cout << "not ok";
    else 
        cout << "ok";
operator bool()Internally returns fail().

Example
    istringstream ssin("10");
    int a;

    //a:10
    //prints ok
    ssin >> a;
    if (ssin)
        cout << "ok";
    else 
        cout << "not ok";
bool void*()nullptr if fail() is true. Otherwise non nullptr.


Example
    istringstream ssin("10");
    int a;

    //a:10
    //prints ok
    if (ssin >> a)
        cout << "ok";
    else 
        cout << "not ok";
iostate rdstate()Returns the current  combined value of the error state.

Example
    istringstream ssin("10");

    //goodbit set   
    bool b = ((ssin.rdstate()) == ios_base::goodbit);
    //eofbit set
    b = ((ssin.rdstate()) & ios_base::eofbit);
    //failbit set
    b = ((ssin.rdstate()) & ios_base::failbit);
    //badbit set
    b = ((ssin.rdstate()) & ios_base::badbit);
void clear
(iostate s = goodbit)
Clears all flags and reset back error state to s.

Example
    istringstream ssin("10");

    //rdstate() == goodbit
    ssin.clear();

    //rdstate() == eofbit
    ssin.clear(ios_base::eofbit);
void setstate
(iostate s)
Does not clear but ORs current error state with s.

Example
    istringstream ssin("10");

    //rdstate() == goodbit
    ssin.clear();

    //rdstate() == eofbit
    ssin.clear(ios_base::eofbit);

    //rdstate() == (eofbit|failbit)
    ssin.setstate(ios_base::failbit);
  1. iostate exceptions()
  2. void exceptions
    (iostate except)
By default a stream does not throw any exceptions. They must explicitly activate an exception from the exception bitmask member. Each flag in this mask corresponds to one of the error flags of type iostate. i.e., eofbit, failbit, and badbit.
For example, once the badbit flag is set in the exception mask, an exception is thrown each time the badbit flag is set in the stream state. The exception type is failure or its derivatives.
  1. Returns the current value of the exception mask for the stream. 
  2. Sets new exception mask for the stream and clears the stream's error state flags with the results same as calling clear().
Generally, it is a good idea to activate the badbit exception and suppress the eofbit and failbit exceptions, because the latter do not represent exceptional states. 

Example
    /*prints
        basic_ios::clear: iostream error
        */
    
    ios strm(nullptr);
    try
    {
        strm.exceptions(ios::badbit); 
    }
    catch (const ios::failure& fail)
    {
        clog << fail.what() << endl;
    }

The example 7 demonstrates usage of the io flags.

Locale

Name
Definition
locale imbue
(const locale& loc)
 Associates loc to both the stream and its associated stream buffer (if any) as the new locale object to be used with locale-sensitive operations.
This function calls its inherited ios_base::imbue() with the loc argument and, if the stream is associated with a stream buffer, it also calls rdbuf()->pubimbue() with the loc argument.
Note that all the derived stream classes such as istreamostream etc call this method.
All callback functions registered with member register_callback() are called by ios_base::imbue().

Example
/*prints
 Mi 04 Dez 2024 19:30:32 UTC UTC
 */
    time_t t = time(nullptr);
    tm tm = *localtime(&t);
 
    cout.imbue(locale("de_DE.utf8"));
    cout << put_time(&tm, "%c %Z") << endl;
char_type widen
(char c)
Converts a character c to its equivalent in the current locale. The result is converted from char to character type used within the stream if needed.
Effectively calls use_facetctype<char_type> >(getloc()).widen(c). If fails returns 0xffffffff.

Example
    cout.imbue(std::locale("de_DE.utf8"));
    //n=78 or 'x'
    auto n = cout.widen('x');

    //n=ffffffff
    n = cout.widen('\xdf'); //'ß'
char_type narrow
(char c, char d)
Converts a character c to its equivalent in the current locale. The result is converted from char to character type used within the stream if needed.
Effectively calls use_facetctype<char_type> >(getloc()).narrow(c). If fails returns character d.

Example
    wcout.imbue(locale("de_DE.utf8"));
    //n=78 or 'x'
    auto n = wcout.narrow('x','x');

    //n=62 or 'b'
    n = wcout.narrow('\xdf','b'); //'ß'

Stream and StreamBuffer
NameDefinition
  1. ostream* tie()
  2. ostream* tie
    (ostream* tiestr)
Manages the tied stream. An input stream and output stream can be tied such that output stream is always flushed before input stream is fetched for input. By default, the standard stream cout is tied to cin and cerr. Similarly, wcout is tied to wcin and wcerr. What this means is, that contents of cout and cerr are always flushed before cin fetches new input.
  1. Returns the current tied stream. If there is no tied stream, a null pointer is returned.
  2. Sets the current tied stream to tiestr. Returns the tied stream before the operation. If there is no tied stream, a null pointer is returned. 
Example
void tietest(bool btie)
{
    string value("");
    ofstream os("output.txt");
    ifstream is("output.txt");
    os << "Hello ";
    if (btie)
        is.tie(&os);
    is >> value;
        
    cout << (btie?"with":"without") << " tie read value:" << quoted(value) << endl;
    os.close();
    is.close();
}

/* prints
without tie read value:""
with tie read value:"Hello"
*/
    
    tietest(false);
    tietest(true);
  1. streambuf* rdbuf()
  2. streambuf*  rdbuf
    (streambuf* sb )
Manages the associated stream buffer.
  1. Returns the associated stream buffer. If there is no associated stream buffer, returns a null pointer.
  2. Sets the associated stream buffer to sb. The error state is cleared by calling clear(). Returns the associated stream buffer before the operation. If there is no associated stream buffer, returns a null pointer. If sb is a null pointer, the function automatically sets the badbit error state flags.

Example
streambuf *psbuf, *backup;
    ofstream filestr;
    filestr.open ("test.txt");

    backup = cout.rdbuf(); 

    psbuf = filestr.rdbuf();
    cout.rdbuf(psbuf);

    cout << "This is written to the file";

    cout.rdbuf(backup);
    filestr.close();

Formatting
NameDefinition
ios& copyfmt 
(
const ios& rhs)
Copies the values of formatting related information  of all the internal members of rhs (except the state flags and the associated stream buffer) to the corresponding members of  the current stream.

The following members are copied:

ElementDescription
flagsformat flags
widthfield width
precisionprecision
getlocselected locale
iarrayinternal extensible array *
parrayinternal extensible array *
fillfill character
tietied stream
exceptionsexceptions mask


Example
vwcout.imbue(locale("de_DE.utf8"));
    //n=78 or 'x'
    auto n = wcout.narrow('x','x');

    //n=62 or 'b'
    n = wcout.narrow('\xdf','b'); //'ß'
  1. char fill()
  2. char fill
    (char ch)

Copy formatting information. The fill character is the character used by output insertion functions to fill spaces when padding results to the field width.
  1. Returns the fill character.
  2. Sets ch as the new fill character and returns the fill character used before the call.
Example
/*prints
        40
xxxxxxxx40
*/
    char prev;

    cout.width (10);
    cout << 40 << endl;

    prev = cout.fill ('x');
    cout.width (10);
    cout << 40 << endl;


No comments:

Post a Comment