C的FILE流中,格式化控制仅影响当前IO操作。
printf("%x\n", 5);
printf("%d\n", 6); //前一个格式控制符%x对本次操作没有影响
然而,C++的IO流却不是如此。
std::cout << std::hex << 5 << std::endl;
std::cout << 20 << std::endl;
// 上一句std::hex操作符改变std::cout流的basefield, 隐藏20将会以16进制输出
为了让20以10进制输出(默认的basefield), 我们需要显式地写明:
std::cout << std::dec << 20 << std::endl;
这里提供一个简单的方法, 让流在一个语句结束后(;)自动恢复为默认fmtflag,主要使用RAII手法和逗号表达式。
#include <ios>
class use_iosbase
{
public:
use_iosbase(std::ios_base& ios) : ios_(ios), fmtflags_(ios_.flags())
{
}
~use_iosbase()
{
ios_.flags(fmtflags_);
}
private:
std::ios_base& ios_;
std::ios_base::fmtflags fmtflags_;
};
#define USE(stream) use_iosbase(stream),stream
#include <iostream>
#include <iomanip>
int main()
{
USE(std::cout) << std::showbase << std::hex << 5 << " " << 6;
USE(std::cout) << std::endl << std::hexfloat << 7.0 << std::endl;
int i;
USE(std::cin) >> std::hex >> i;
USE(std::cout) << i;
}