2016-07-12 5 views
0

Also weiß ich, dass ich die Formatierungsänderungen, die ich mit iomanip gemacht habe, oft zurücksetzen wollte. Ich habe eine Klasse erstellt, die Sie verwenden können, um die Formatierung eines Ostream-Objekts wie std :: cout oder fstream-Objekte zum Schreiben/Lesen von Dateien zu erhalten. Ich mache das hauptsächlich für die Praxis und um anderen zu helfen, die das gleiche Problem haben.Klasse, die alle mit iomanip vorgenommenen Änderungen zurücksetzt: setprecision, setfill und die Flags in einem Aufruf

Alles, was Sie tun müssen, ist ein Objekt mit der Klasse ResetIOmanip erstellen. Wenn Sie es ohne Parameter erstellen, wird standardmäßig std :: cout verwendet. Sie können ostream/istream-Objekte als Parameter einfügen und es wird für die Dateien funktionieren. Stellen Sie sicher, dass Sie es aufrufen, bevor Sie Formatänderungen vornehmen. Wenn dies abgeschlossen ist, rufen Sie die Memberfunktion resetAll() vom Objekt auf, und die Flags werden zurückgesetzt, die Genauigkeit zurückgesetzt und das Füllzeichen zurückgesetzt.

Bitte zögern Sie nicht zu kommentieren, wie ich meine Header-Datei verbessern kann. Ich lerne immer noch und suche immer nach konstruktiver Kritik. Vielen Dank. Hier

Antwort

2

ist die Header-Datei:

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 

Hier ist, wie ich es getestet:

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; 
} 
+1

Ich finde Sachen wie diese sind nützlich. Hier ist eine Variante, die ich in letzter Zeit verwendet habe: https://github.com/HowardHinnant/date/blob/master/date.h#L850-L875 Es speichert nicht "Präzision", nur weil ich es nicht brauchte. Das könnte leicht hinzugefügt werden (und ich sollte wahrscheinlich). Sie können anstelle von 'ostream *' und 'istream' '' std :: ios * 'verwenden (beide stammen von' ios' und dort wird die Formatierung gespeichert). Ich stelle im Destruktor wieder her. So wird es immer gemacht, auch in Ausnahmefällen. Deshalb mache ich meinen Resetter nicht kopierbar. –

Verwandte Themen