Home >Backend Development >C++ >Why Do Some C Iomanipulators Exhibit 'Sticky' Behavior?

Why Do Some C Iomanipulators Exhibit 'Sticky' Behavior?

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

Why Do Some C   Iomanipulators Exhibit

Manipulators and Their 'Sticky' Nature in C

In C , certain iomanip manipulators exhibit a behavior known as 'stickiness,' where they continue to influence the stream until explicitly reset. This behavior can lead to unexpected results, as seen in the following code snippet:

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 this example, we expect the setw() manipulator to format the tm_mday field with a width of 2 and right-justify the output. However, tm_hour and tm_min are printed without any formatting. This is because setw() is not a 'sticky' manipulator, meaning it only affects the next insertion operation.

Which Manipulators are Sticky?

Based on the discussion in the comments, the following manipulators are classified as 'sticky':

  • setiosflags
  • resetiosflags
  • setbase
  • setfill
  • setprecision

These manipulators all return an object rather than a stream, indicating that they perform an operation only on the next object to be inserted into the stream.

Non-Sticky Manipulators

  • [no]boolalpha
  • [no]showbase
  • [no]showpoint
  • [no]showpos
  • [no]skipws
  • [no]unitbuf
  • [no]uppercase
  • dec/hex/oct
  • fixed/scientific
  • internal/left/right
  • ws/endl/ends/flush

These manipulators perform operations on the stream itself, without affecting its state for subsequent operations.

The Exception: setw()

Notably, setw() is the only manipulator that appears to behave differently on the author's system. While it is not a 'sticky' manipulator, it can be made to behave like one using custom format objects, as demonstrated in the following code:

#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
}

Output:

5.34
[5.3400000000]
5.34

In summary, most iomanip manipulators in C are 'sticky,' meaning they continue to affect the stream until explicitly reset. setw() is the notable exception, but it can be made 'sticky' using custom format objects.

The above is the detailed content of Why Do Some C Iomanipulators Exhibit 'Sticky' Behavior?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn