cin

cin的基本规则:接触到非空白字符(空格,制表,换行)即开始阅读,遇到空白字符即停止阅读。

istream.get()可以读取一个字符

  1. cin.get():获取一个字符,包括空白字符。如果遇到结束符号,则返回-1
  2. cin.get(char)读取一个字符,到指定字符中。
  3. cin.get(char*, int, char):读取到字符串/数组中,直到指定个数,或者遇到终止字符。

istream.getline(char*, int, char)可以读取一串字符

  1. 提取一行字符到字符串/数组中,直到指定个数,或遇到终止字符。

istream.peek()

  • 观测下一个字符,指针并不后移。

istream.putback(char)

  • 将一个字符添加到输入流中,下一个将会读到。

istream.ignore()

  • 跳过n个字符,或者直到遇到了终结字符。
  • 实质是修改流缓冲的指针:basic_streambuf._Gnext

cout

ostream.flush()

  • 实质是清空缓冲流ios._Mystrbuf

缓冲区

文件描述符是数字,是操作系统的概念。默认情况下,文件描述符 0, 1, 2都连接到终端 /dev/ptsx的。

stdin是一个文件指针,类型为 FILE*,也就是「流」,这是 C 语言的概念。默认情况下,stdin连接到进程的文件描述符 0,例如 /dev/tty/xxxstdinstdout是有缓冲的,这个缓冲是用户区缓冲,是 C 语言提供的;而 stderr 没有缓冲。

cinbasic_istream类型的全局变量。
以下部分是猜想:cin连接到进程的文件描述符 0;C++ 为 cin 提供了缓冲,也就是所谓的流缓冲。
为什么不要混用 coutprintf,因为两者使用不同的缓冲机制;听说 C++ 会将自身的流缓冲和 C 的输出缓冲区同步。
注:cerr是无缓冲的。
Pasted Graphic.png
为什么需要缓冲区:因为 write()是系统调用,消耗比较大(涉及到从用户态到内核态的切换),减少调用次数可以提高效率。

参考:https://stackoverflow.com/questions/21084218/difference-between-write-and-printf

格式控制

格式控制的两种方式

  • 通过具体的参数
    • 通过方法设置参数:cout.width(int)
    • 通过操作器设置参数:cout << setw(int)
  • 通过设置flags
    • 通过方法设置flagscout.setf(ios::fmtflags)
    • 通过有参数操作器设置flagscout << setiosflags(ios::fmtflags)
    • 通过无参数操作器设置flagscout << flags_funcPtr

通过格式标志控制格式

常用的标志有:

标志 说明
boolalpha, noboolalpha 布尔值显示为true
还是1
oct, dec, hex 显示进制
left, right 对齐方式,需要以显示宽度为前提
scientific 科学计数法形式输出浮点数
fixed 以普通小数形式显示浮点数
showpos, noshowpos 非负值显示+
skipws, noskipws 输入时跳过空白字符
uppercase, nouppercase 十六进制,科学计数法的字符大/小写

设置参数控制格式

  1. // 设置显示宽度,超出会截断,不足以空白填充
  2. cout << setw(int);
  3. cout.width(int);
  4. // 设置填充字符
  5. cout << setfill(char);
  6. cout.fill(char);
  7. // 设置浮点数的显示精度
  8. cout << setprecision(int);
  9. cout.precision(int);
  10. // 设置整数显示的进制
  11. cout << setbase(int);