In C zeigen bestimmte iomanip-Manipulatoren ein Verhalten, das als „Klebrigkeit“ bekannt ist und bei dem sie den Stream bis dahin weiterhin beeinflussen explizit zurückgesetzt. Dieses Verhalten kann zu unerwarteten Ergebnissen führen, wie im folgenden Codeausschnitt zu sehen ist:
std::stringstream ss; ss.fill('0'); ss.setf(ios::right, ios::adjustfield); ss << setw(2) << timestruct.tm_mday; ss << timestruct.tm_hour; ss << timestruct.tm_min; std::string filingTime = ss.str(); // BAD: '0794'
In diesem Beispiel erwarten wir, dass der setw()-Manipulator das Feld tm_mday mit einer Breite von 2 formatiert und rechtsbündig ausrichtet die Ausgabe. Allerdings werden tm_hour und tm_min ohne jegliche Formatierung gedruckt. Dies liegt daran, dass setw() kein „Sticky“-Manipulator ist, was bedeutet, dass er sich nur auf den nächsten Einfügevorgang auswirkt.
Basierend auf der Diskussion in den Kommentaren Folgendes Manipulatoren werden klassifiziert als 'sticky':
Diese Manipulatoren geben alle ein Objekt und keinen Stream zurück, was darauf hinweist, dass sie Führen Sie eine Operation nur für das nächste Objekt aus, das in den Stream eingefügt werden soll.
Diese Manipulatoren führen Operationen am Stream selbst aus, ohne seinen Zustand für nachfolgende Operationen zu beeinflussen.
Bemerkenswerterweise ist setw() der einzige Manipulator, der sich auf dem Stream anders zu verhalten scheint Autorensystem. Obwohl es sich nicht um einen „klebrigen“ Manipulator handelt, kann er mithilfe benutzerdefinierter Formatobjekte so eingestellt werden, dass er sich wie einer verhält, wie im folgenden Code gezeigt:
#include <iostream> #include <iomanip> struct SquareBracktAroundNextItem { SquareBracktAroundNextItem(std::ostream& str) : m_str(str) {} std::ostream& m_str; }; struct PutSquareBracket {}; SquareBracktAroundNextItem operator<<(std::ostream& str, PutSquareBracket const& data) { return SquareBracktAroundNextItem(str); } template<typename T> std::ostream& operator<<(SquareBracktAroundNextItem const& bracket, T const& data) { std::ios_base::fmtflags flags = bracket.m_str.flags(); std::streamsize currentPrecision = bracket.m_str.precision(); bracket.m_str << '[' << std::fixed << std::setprecision(10) << data << std::setprecision(currentPrecision) << ']'; bracket.m_str.flags(flags); return bracket.m_str; } int main() { std::cout << 5.34 << "\n" // Before << PutSquareBracket() << 5.34 << "\n" // Temp change settings. << 5.34 << "\n"; // After }
Ausgabe:
5.34 [5.3400000000] 5.34
Zusammenfassend lässt sich sagen, dass die meisten iomanip-Manipulatoren in C „sticky“ sind, was bedeutet, dass sie den Stream weiterhin beeinflussen, bis sie explizit zurückgesetzt werden. setw() ist die bemerkenswerte Ausnahme, kann jedoch mithilfe benutzerdefinierter Formatobjekte „klebrig“ gemacht werden.
Das obige ist der detaillierte Inhalt vonWarum zeigen einige C-Imanipulatoren ein „klebriges' Verhalten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!