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.
Based on the discussion in the comments, the following manipulators are classified as 'sticky':
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.
These manipulators perform operations on the stream itself, without affecting its state for subsequent operations.
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!