20 Stimmen

Einstellung der Breite im C++-Ausgabestrom

Ich versuche, eine sauber formatierte Tabelle in C++ zu erstellen, indem ich die Breite der verschiedenen Felder einstelle. Ich kann setw(n) verwenden, indem ich etwas tue wie

cout << setw(10) << x << setw(10) << y << endl;

oder ändern Sie ios_base::width

cout.width (10);
cout << x;
cout.width (10);
cout << y << endl;

Das Problem ist, dass keine der beiden Alternativen mir erlaubt, eine Standard-Mindestbreite festzulegen, und ich muss sie jedes Mal ändern, wenn ich etwas in den Stream schreiben will.

Kennt jemand eine Möglichkeit, wie ich dies tun kann, ohne denselben Anruf unzählige Male wiederholen zu müssen? Vielen Dank im Voraus.

0 Stimmen

1 Stimmen

Bezieht sich auf die Klebrigkeit der verschiedenen iomanip-Manipulatoren. setw ist NICHT klebrig: stackoverflow.com/questions/1532640/

0 Stimmen

Okay, tut mir leid. Ich habe schon einmal nach etwas Ähnlichem gesucht, aber ohne Erfolg. Die Antworten hier und in den anderen Beiträgen gaben mir ein gutes Verständnis dafür, wie ich es lösen kann, danke.

21voto

Jason Punkte 30904

Sie können ein Objekt erstellen, das die operator<< und enthält eine iostream Objekt, das automatisch die setw innerlich. Zum Beispiel:

class formatted_output
{
    private:
        int width;
        ostream& stream_obj;

    public:
        formatted_output(ostream& obj, int w): width(w), stream_obj(obj) {}

        template<typename T>
        formatted_output& operator<<(const T& output)
        {
            stream_obj << setw(width) << output;

            return *this;
        }

        formatted_output& operator<<(ostream& (*func)(ostream&))
        {
            func(stream_obj);
            return *this;
        }
};

Sie können es nun wie folgt aufrufen:

formatted_output field_output(cout, 10);
field_output << x << y << endl;

3 Stimmen

+1, danke! Falls es noch jemanden interessiert: die zweite operator<< ermöglicht es der Klasse, mit Funktionen wie std::endl wie beschrieben ici . Ich hoffe, das hilft allen anderen neugierigen Katzen, die @Jasons Code auseinandernehmen...

1voto

ssell Punkte 6120

Ich weiß, dass dies immer noch derselbe Anruf ist, aber ich kenne keine andere Lösung, wie ich aus Ihrer Frage entnehme.

#define COUT std::cout.width(10);std::cout<<

int main()
{
    std::cout.fill( '.' );

    COUT "foo" << std::endl;
    COUT "bar" << std::endl;

    return 0;
}

Ausgabe:

..........foo
..........bar

2 Stimmen

Warum ein Makro verwenden, wenn eine Vorlage leicht erstellt werden kann und sogar die Verkettung von Ausgaben ermöglicht?

0voto

Ray Punkte 577

Warum nicht einfach eine Funktion erstellen?

Pseudocode z.B.

void format_cout(text, w) {
 cout << text << width(w);
}

Das ist ein bisschen dürftig, aber ich hoffe, Sie verstehen die Idee.

0 Stimmen

Dieser Ansatz ist schön und einfach, aber er erlaubt nicht die Verwendung von verketteten operator<<s . Es würde auch (Leerzeichen-)Probleme verursachen, wenn Sie versuchen, die std::endl ...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X