C++输出cout格式控制与定制

目录

输出格式化

控制函数

格式标志

控制符

定制输出

重定向至文件

同步输出


​​​​​​​

cout是STL库中的iostream实例,用于格式化输出。

输出格式化

格式相关操作需包含<iomanip>,标志位等定义在<ios>或<iostream>中。

控制函数

格式控制的成员一般有对应的控制符(在cout输出中使用)。

  • precision(n):对应setprecision(n),设置实数的精度;
  • width(n):对应setw(n),设置字段宽度为n位;
  • fill(c):对应setfill(c),设置填充字符为c;
  • setf(f):对应setiosflags(f),设置输出格式状态;
  • unsetf(f):对应resetioflags(f),删除格式状态;

如,以下两种方式是等价的:

for(int i=0;  i<10; ++i){
  cout<<setw(2)<<n+1<<endl;
}

for(int i=0;  i<10; ++i){
  cout.width(2);
  cout<<n+1<<endl;
}

格式标志

cout维护一个当前的格式状态,setf/unsetf在当前状态基础上追加或移除指定格式,而flags则是直接指定格式(替换掉当前格式)。每种格式独占一位,可用或操作组合。

  • ios::dec 以10进制表示整数
  • ios::hex 以16进制表示整数
  • ios::oct 以8进制表示整数
  • ios::showbase 强制输出整数基数前缀(八进制0,十六进制0x)
  • ios::internal 在符号位和数值的中间插入需要数量的填充字符以使串两端对齐
  • ios::left 左对齐
  • ios::right 右对齐
  • ios::boolalpha 将bool类型的值以true或flase显示
  • ios::fixed 符点数以定点格式(小数形式)输出
  • ios::scientific 将符点数按照科学计数法处理(带指数域)
  • ios::showpoint 强制输出浮点数的小数点和尾数0(如1.00000)
  • ios::showpos 强制在正数前添加+号
  • ios::skipws 忽略前导的空格(主要用于输入流,如cin)
  • ios::unitbuf 在插入(每次输出)操作后清空缓存
  • ios::uppercase 强制大写字母

控制符

为方便使用,定义了相应的控制符(如std::setw(n),std::showpos等),可在cout中可以直接使用以对流进行控制:

  • boolalpha/noboolalpha:布尔值输出方式文本(true/false)或数值(0/1)
  • showbase/noshowbase:控制是否显示前缀指示数值基数
  • showpoint/noshowpoint:控制浮点表示是否始终包含小数点
  • showpos/noshowpos:控制是否将+号
  • skipws/noskipws:控制是否跳过输入上的前导空白符(cin时)
  • uppercase/nouppercase:控制是否使用大写字母输出
  • unitbuf/nounitbuf:控制是否每次操作后是否冲洗输出
  • internal/left/right:设置对齐方式
  • dec/hex/oct:更改整数I/O的基数
  • fixed/scientific/hexfloat/defaultfloat:更改用于浮点I/O的格式
  • ws:消耗空白符(cin)
  • ends:输出 '\0'
  • flush:冲洗输出流
  • endl:输出 '\n' 并冲洗输出流
  • resetiosflags(f):清除指定的标志
  • setiosflags(f):设置指定的标志
  • setbase(n):更改用于整数I/O的基数
  • setfill(c):更改填充字符
  • setprecision(n):更改浮点精度
  • setw(n):更改下个输入/输出域的宽度
  • get_money(m):剖析货币值
  • put_money(m):格式化并输出货币值
  • get_time(t):剖析指定格式的日期/时间值
  • put_time(t):按照指定格式格式化并输出日期/时间值
  • quoted(str):插入和读取带有内嵌空格的被引号括起来的字符串
int n=123;
cout<<showpos<<showbase<<n<<", "<<hex<<n<<endl;
// 输出: +123, 0x7b

time_t t = time(nullptr);
tm tm = *localtime(&t);
cout.imbue(locale("ru_RU.utf8"));
cout << "ru_RU: " << put_time(&tm, "%c %Z") << '\n';
// ru_RU: Ср. 28 дек. 2011 10:21:16 EST
cout.imbue(locale("ja_JP.utf8"));
cout << "ja_JP: " << put_time(&tm, "%c %Z") << '\n';
// ja_JP: 2011年12月28日 10時21分16秒 EST

控制符有些具有粘性(持续影响接下来的输入、输出,直到对控制符重置);有些没有(只对下一次输入、输出有影响),如setw、quoted。

定制输出

可以定制cout以满足需要。

重定向至文件

有时需要把cout输出重定向文件,方便处理或保存。

class redirect_cout{
  using bufType=decltype(cout.rdbuf());
  ofstream ofs;
  bufType bufBack;

public:
  explicit redirect_cout(const string &fName)
    : ofs(fName), bufBack{cout.rdbuf(ofs.rdbuf()}
  {}

  ~redirect_cout(){
    cout.rdbuf(bufBack);
  }
}


redirect_cout tmp{"c:\\tmp\\out.log"};
bool bTest = true;
cout<<boolalpha<<bTest<<endl; // 输出到out文件中了

同步输出

在多线程环境下使用cout输出时,会乱掉(互相影响),为此可封装同步的cout来进行输出:

struct synOut:public stringstream{
  static mutex mtx;

  ~synOut(){
    lock_guard<mutex> lker(mtx);
    cout<<rdbuf()<<flush;
  }
}
mutex synOut::mtx;

void thrOne(int nIndex){
  // ...
  synOut{}<<"thread-one: "<<nIndex<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值