Heim >Backend-Entwicklung >C++ >Warum zeigen einige C-Imanipulatoren ein „klebriges' Verhalten?

Warum zeigen einige C-Imanipulatoren ein „klebriges' Verhalten?

Patricia Arquette
Patricia ArquetteOriginal
2024-12-25 19:32:10778Durchsuche

Why Do Some C   Iomanipulators Exhibit

Manipulatoren und ihre „klebrige“ Natur in C

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.

Welche Manipulatoren sind Sticky?

Basierend auf der Diskussion in den Kommentaren Folgendes Manipulatoren werden klassifiziert als 'sticky':

  • setiosflags
  • resetiosflags
  • setbase
  • setfill
  • setprecision

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.

Nicht klebrig Manipulatoren

  • [no]boolalpha
  • [no]showbase
  • [no]showpoint
  • [no]showpos
  • [no]skipws
  • [no]unitbuf
  • [kein]Großbuchstabe
  • dez/hex/okt
  • fest/wissenschaftlich
  • intern/links/rechts
  • ws/endl /ends/flush

Diese Manipulatoren führen Operationen am Stream selbst aus, ohne seinen Zustand für nachfolgende Operationen zu beeinflussen.

Die Ausnahme: setw()

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn