目录
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;
}