2 - 用户流iostream
主要是对cin
和cout
做一些补充。
输出流cout
除了<<
运算符外,还能在<ostream>
,<ios>
,<iomanip>
等头文件中找到一些额外功能:
方法
put() 和 write()
它们是原始的输出方法,前者接收单个字符,后者接收整个字符数组:
const char* test {"Hello\n"};
cout.put('a');
cout.write(test, strlen(test));
flush()
当向输出流写入数据时,流不一定会将数据立即写入目的地,而是进行缓冲最后一齐写入以提高性能。在以下情况下,输出流将刷新/输出数据:
- 遇到
std::endl
- 流离开它的作用域被析构
- 流的缓冲区满
- 显式要求流刷新缓冲区
- 要求从对应的输入流输入数据时(例如从
cin
输入时,cout
会刷新)
而cout.flush()
就是显式要求流刷新缓冲区
操作算子
endl
它封装了数据和行为,要求流输出一个行结束序列,并刷新缓冲区。
boolalpha 和 noboolalpha
如果是前者,将布尔值输出为true或false;如果是后者,将布尔值输出为1或0。默认为后者。
hex,oct,dec
分别以十六进制,八进制,和十进制输出数字
setprecision(x)
设置输出小数的位数。
setw(x)
设置输出数据的宽度
setfill(x)
将一个字符设置为流的新填充字符,填充字符根据数据宽度进行填充输出。
showpoint 和 noshowpoint
对于没有小数部分的浮点数,输出是否显示小数点。
put_money(x)
向流写入一个格式化的货币值
put_time(x)
向流写入一个格式化的时间值
quoted(x)
把给定的字符串封装在引号中,并转义嵌入的引号。
上述操作算子对后续输出到流的内容中有效,直到重置操作算子位置。但 setw(x) 仅对下一个输出有效。
输入流cin
与输出流一样,输入流也提供了一些方法和操作算子。
方法
这些方法可获得相对>>
运算符更底层的访问功能。
get()
从流中读入原始输入数据,可以读一个字符,返回下一个字符;也可以一次读入多个字符。该方法常用于避免>>
运算符的自动标志化。
一段读取英文名的代码如下:
// 版本1 get(), 读一个字符返回一个字符
string readName(istream& stream)
{
string ret;
while (stream)
{
int next = stream.get();
if (!stream || next == char_traits<char>::eof())
break;
name += static_cast<char>(next);
}
return ret;
}
// 版本2 get(x), 接收字符引用x,返回流引用
string readName(istream& stream)
{
string ret;
char next;
while (stream.get(next))
{
ret += next;
}
return ret;
}
unget()
调用它会导致流回退一个位置,将读入的前一个字符放回流中。调用fail()
可以查看此操作是否失败。
putback()
类似unget()
,但它接收一个参数作为放回流中的字符。
peek()
它可以预览调用get()
后返回的下一个值,但不把值从流中取出来。
getline()
从输入流中读取一行,直到行尾/指定大小为止。
char buffer[kBufferSize] { 0 };
cin.getline(buffer, kBufferSize);
操作算子
boolalpha 和 noboolaplha
前者将字符串"false"
解析为布尔值false
,其他字符串都是布尔值true
;后者将0解析为布尔值false
,其他任何值都是true
。默认为后者。
dec,hex 和 oct
分别读取十进制,十六进制和八进制的数据。
skipws 和 noskipws
告诉输入流在标记化时跳过空白字符,或者读入空白字符作为标记。默认为前者。
ws
跳过流中当前位置的一串空白字符
get_money(x)
从流中读入一个格式化的货币值
get_time(x)
从流中读入一个格式化的时间值
quoted(x)
读取封装在引号中的字符串,并转义嵌入的引号。
参考资料
- 飘零的落花 - 现代C++详解
- C++20高级编程