Ich habe einige Probleme beim Versuch, eine benutzerdefinierte Stream-Klasse zu implementieren, um gut eingerückt Code in einer Ausgabedatei zu generieren. Ich habe online intensiv gesucht, aber es scheint keinen Konsens darüber zu geben, wie dies am besten erreicht werden kann. Einige Leute sprechen über den Strom abzuleiten, andere sprechen über den Puffer abzuleiten, noch andere schlagen die Verwendung von locales/Facetten usw.C++ benutzerdefinierte Ausgabe Stream mit Einzug
Im Wesentlichen Ich finde mich viel Code wie folgt schreiben:
ofstream myFile();
myFile.open("test.php");
myFile << "<html>" << endl <<
"\t<head>" << endl <<
"\t\t<title>Hello world</title>" << endl <<
"\t</head>" << endl <<
"</html>" << endl;
Wenn starten die Reiter aufzuaddieren es schrecklich aussieht, und es scheint, wie es wäre schön, so etwas zu haben:
ind_ofstream myFile();
myFile.open("test.php");
myFile << "<html>" << ind_inc << ind_endl <<
"<head>" << ind_inc << ind_endl <<
"<title>Hello world</title>" << ind_dec << ind_endl <<
"</head>" << ind_dec << ind_endl <<
"</html>" << ind_endl;
dh eine abgeleitete Stream-Klasse erstellen, die den Überblick über ihre aktuellen indent Tiefe halten würde, dann einige Manipulatoren, um den Einzug zu vergrößern/verkleinern Tiefe und ein Manipulator, um einen Zeilenumbruch gefolgt von so vielen Tabs zu schreiben.
hier ist also meine Chance auf den Klassen Umsetzung & Manipulatoren:
ind_ofstream.h
class ind_ofstream : public ofstream
{
public:
ind_ofstream();
void incInd();
void decInd();
size_t getInd();
private:
size_t _ind;
};
ind_ofstream& inc_ind(ind_ofstream& is);
ind_ofstream& dec_ind(ind_ofstream& is);
ind_ofstream& endl_ind(ind_ofstream& is);
ind_ofstream.cpp
ind_ofstream::ind_ofstream() : ofstream() {_ind = 0;}
void ind_ofstream::incInd() {_ind++;}
void ind_ofstream::decInd() {if(_ind > 0) _ind--;}
size_t ind_ofstream::getInd() {return _ind;}
ind_ofstream& inc_ind(ind_ofstream& is)
{
is.incInd();
return is;
}
ind_ofstream& dec_ind(ind_ofstream& is)
{
is.decInd();
return is;
}
ind_ofstream& endl_ind(ind_ofstream& is)
{
size_t i = is.getInd();
is << endl;
while(i-- > 0) is << "\t";
return is;
}
Dies baut, erzeugt aber keine die erwartete Ausgabe ; Jeder Versuch, die benutzerdefinierten Manipulatoren zu verwenden, führt dazu, dass sie aus irgendeinem Grund in einen booleschen Wert umgewandelt werden und "1" in die Datei geschrieben wird. Muss ich den Operator < < für meine neue Klasse überladen? (Ich war nicht in der Lage, einen Weg zu finden, dies zu tun, das baut)
Vielen Dank!
p.s.
1) Ich habe das # includes weggelassen, Namespace usw. aus meinen Code-Schnipsel zu verwenden, um Platz zu sparen.
2) Ich möchte in der Lage sein, eine Schnittstelle ähnlich der in meinem zweiten Code-Snippet zu verwenden. Wenn Sie nach der Lektüre der ganzen Post denken, dass das eine schlechte Idee ist, erklären Sie bitte warum und bieten Sie eine Alternative an.
Frage: Wenn das gewünschte Ergebnis ein sauberer Code und eine korrekte Ausgabe ist - das heißt, wenn dies nicht nur akademisch ist oder zu Ihrer eigenen Verbesserung - warum schreiben Sie [HT | X] ML direkt auf diese Weise? Zumindest könnten Sie es auf Disc UNincured schreiben, dann verwenden Sie etwas Prettifier (zum Beispiel, um diese schmutzige Arbeit zu erledigen). ... dass es interessant ist, und ich habe ein fettiges Gefühl, dass ich bald eine Lösung zusammen schmieden werde. :) – Christopher
Hallo - das ist eine gute Idee und wahrscheinlich, was ich am Ende tun werde, wenn ich Plan A nicht zum Arbeiten bekommen kann. Ich finde Streams als einen der verwirrenderen Aspekte von C++, also dachte ich mir, dies könnte ein guter Weg sein, ein tieferes Verständnis dafür zu bekommen, wie sie funktionieren ... – user1898153