Search code examples
c++iomanip

Class that resets all of the changes made with iomanip: setprecision, setfill and the flags in one call


So I know that there was plenty of times where I wanted to reset the formatting changes that I made with using iomanip. I created a class that you can use to get the formatting of an ostream object such as std::cout or fstream objects for writing/reading files will work as well. I am doing this for mainly practice and to help others who has the same issue.

All you have to do is create an object using the class ResetIOmanip. If you create it with no parameters, it will use std::cout as default. You can put ostream/istream objects in as the parameters and it will work for the files. Make sure you call it before making any format changes. Then when it is complete call the member function resetAll() from the object and it will reset the flags, reset the precision, and reset the fill character.

Please feel free to give comments on how I can improve my header file. I am still learning and am always looking for constructive criticism. Thanks.


Solution

  • Here is the header file:

    ResetIOmanip.h

    /*
    File:   ResetIOmanip.h
    Author: kingcobra1986
    Date:   7/11/2016
    Class:  ResetIOmanip
    Purpose: 
            When the instance of the class ResetIOmanip is created, the 
            current settings will be saved and can be recalled by calling
            the member function resetAll().
    */
    
    #ifndef _RESETIOMANIP
    #define _RESETIOMANIP
    #include <iostream>
    #include <iomanip>
    
    class ResetIOmanip {
    private:
        std::ostream * _ostream;
        std::istream * _istream;
        std::streamsize _precision;
        std::ios_base::fmtflags _flags;
        char _fill;
    
        //Set the original precision
        void set_precision () {
            if (this->_ostream != nullptr)
                this->_precision = this->_ostream->precision ();
            if (this->_istream != nullptr)
                this->_precision = this->_istream->precision ();
        }
    
        //Set the original flags
        void set_flags () { 
            if (this->_ostream != nullptr)
                this->_flags = this->_ostream->flags ();
            if (this->_istream != nullptr)
                this->_flags = this->_istream->flags ();
        }
    
        //Set the original fill
        void set_fill () { 
            if (this->_ostream != nullptr)
                this->_fill = this->_ostream->fill ();
            if (this->_istream != nullptr)
                this->_fill = this->_istream->fill ();
        }
    
    public:
        //Default Constructor
        ResetIOmanip ( std::ostream & stream = std::cout ) {
            this->_ostream = &stream;
            this->_istream = nullptr;
            this->set_precision ();
            this->set_flags ();
            this->set_fill ();
            stream << "Fill: " << this->get_fill () << std::endl;
        }
    
        //Overloaded Constructor
        ResetIOmanip ( std::istream & stream ) {
            this->_ostream = nullptr;
            this->_istream = &stream;
            this->set_precision ();
            this->set_flags ();
            this->set_fill ();
        }
    
        //Get the original precision
        std::streamsize get_precision () { return this->_precision; }
    
        //Get the original flags
        std::ios_base::fmtflags get_flags () { return this->_flags; }
    
        //Get the original fill
        char get_fill () { return this->_fill; }
    
        //Reset to the original precision
        void reset_precision () {
            if (this->_ostream != nullptr)
                this->_ostream->precision ( this->_precision );
            if (this->_istream != nullptr)
                this->_istream->precision ( this->_precision );
        }
    
        //Reset to the original flags
        void reset_flags () {
            if (this->_ostream != nullptr)
                this->_ostream->flags ( this->_flags );
            if (this->_istream != nullptr)
                this->_istream->flags ( this->_flags );
        }
    
        //Reset to the original fill
        void reset_fill () { 
            if (this->_ostream != nullptr) {
                this->_ostream->fill ( this->_fill );
            }
            if (this->_istream != nullptr)
                this->_istream->fill ( this->_fill );
        }
    
        //Reset to all of the original settings
        void resetAll () {
            this->reset_precision ();
            this->reset_flags ();
            this->reset_fill ();
        }
    };
    
    #endif
    

    Here is how I tested it:

    Main.cpp

    //This is to test ResetIOmanip objects
    #include <iostream>
    #include <fstream>
    #include "ResetIOmanip.h"
    
    int main () {
        using std::cout;
        using std::endl;
    
        double randNumb1 = 45.235723;
        double randNumb2 = 1.49;
    
        ResetIOmanip resetFormats1;
        cout << "Original 1: " << randNumb1 << endl;
        cout << "Original 2: " << randNumb2 << endl;
        cout << "setprecision(4) for #1: " << std::setprecision ( 4 ) << randNumb1 << endl;
        cout << "setprecision(4) for #2: " << std::setprecision ( 4 ) << randNumb2 << endl << endl;
    
        cout << "setprecision(4) and fixed for #1: " << std::fixed << std::setprecision ( 4 ) << randNumb1 << endl;
        cout << "setprecision(4) and fixed for #2: " << std::fixed << std::setprecision ( 4 ) << randNumb2 << endl;
    
        cout << "setfill(x) and setw(10) for #1: " << std::setfill ( 'x' ) << std::setw ( 10 ) << randNumb1 << endl;
        cout << "setfill(x) and setw(10) for #2: " << std::setfill ( 'x' ) << std::setw ( 10 ) << randNumb2 << endl << endl;
    
        cout << "Testing Format #1: " << randNumb1 << endl;
        cout << "Testing Format #2: " << randNumb2 << endl;
    
        cout << "Testing Format with set width(10) #1: " << std::setw(10) << randNumb1 << endl;
        cout << "Testing Format with set width(10) #2: " << std::setw ( 10 ) << randNumb2 << endl << endl;
    
        cout << "RESETING - TESTING CLASS" << endl;
    
        resetFormats1.resetAll ();
        cout << "Testing Format #1: " << randNumb1 << endl;
        cout << "Testing Format #2: " << randNumb2 << endl;
    
        cout << "Testing Format with set width(10) #1: " << std::setw ( 10 ) << randNumb1 << endl;
        cout << "Testing Format with set width(10) #2: " << std::setw ( 10 ) << randNumb2 << endl << endl;
    
    
    
        cout << "Testing with ostream to testResetIOmanip.txt" << endl;
        std::ofstream testingOut;
        testingOut.open ( "testResetIOmanip.txt", std::ios::out );
        if (testingOut.fail ()) {
            cout << "ERROR: Cannot open the file" << endl;
            return 0;
        }
        ResetIOmanip resetFormats2 ( testingOut );
    
        testingOut << "Original 1: " << randNumb1 << endl;
        testingOut << "Original 2: " << randNumb2 << endl;
        testingOut << "setprecision(4) for #1: " << std::setprecision ( 4 ) << randNumb1 << endl;
        testingOut << "setprecision(4) for #2: " << std::setprecision ( 4 ) << randNumb2 << endl << endl;
    
        testingOut << "setprecision(4) and fixed for #1: " << std::fixed << std::setprecision ( 4 ) << randNumb1 << endl;
        testingOut << "setprecision(4) and fixed for #2: " << std::fixed << std::setprecision ( 4 ) << randNumb2 << endl;
    
        testingOut << "setfill(x) and setw(10) for #1: " << std::setfill ( 'x' ) << std::setw ( 10 ) << randNumb1 << endl;
        testingOut << "setfill(x) and setw(10) for #2: " << std::setfill ( 'x' ) << std::setw ( 10 ) << randNumb2 << endl << endl;
    
        testingOut << "Testing Format #1: " << randNumb1 << endl;
        testingOut << "Testing Format #2: " << randNumb2 << endl;
    
        testingOut << "Testing Format with set width(10) #1: " << std::setw ( 10 ) << randNumb1 << endl;
        testingOut << "Testing Format with set width(10) #2: " << std::setw ( 10 ) << randNumb2 << endl << endl;
    
        testingOut << "RESETING - TESTING CLASS" << endl;
        resetFormats2.resetAll ();
    
        testingOut << "Testing Format #1: " << randNumb1 << endl;
        testingOut << "Testing Format #2: " << randNumb2 << endl;
    
        testingOut << "Testing Format with set width(10) #1: " << std::setw ( 10 ) << randNumb1 << endl;
        testingOut << "Testing Format with set width(10) #2: " << std::setw ( 10 ) << randNumb2 << endl << endl;
    
        testingOut.close ();
    
        return 0;
    }