【C++】输入输出

一、缓冲

C++ 的输入输出均通过缓冲区来实现。缓冲区主要是为了解决速度不匹配的问题。

二、输入(cin)

阻塞输入。当输入缓存中无字符时则等待用户输入。

输入缓冲

输入缓冲是一种行缓冲。在输入数据只要没有碰到换行符(回车)就将数据存入输入缓冲区,当碰到换行符之后就将缓冲区中的数据取出供变量使用,但是缓冲区中的换行符会被留在输入缓冲区中。

cin>>

  • 读取:从输入缓存中直接读取(若输入缓存无有效字符,则要求用户输入)。
  • 不读取缓存首部的无效字符(空格、回车、换行)。
  • 结束条件:空格、回车、换行。
  • 其余字符留在缓存区中。

cin.get

a=cin.get() 或 cin.get(a)

  • 读取:从输入缓存中直接读取一个字符(若输入缓存无字符,则要求用户输入)。
  • 任意字符均可,包括无效字符(空格、回车、换行)。

cin.get(arrayname,size)

  • 读取:从输入缓存中直接读取(若输入缓存无字符,则要求用户输入)。
  • 若缓存首部为空格、换行,则直接读取。
  • $\star$ 若缓存首部为换行符,则将 '\0' 赋给目标,设置失效位failbit,缓冲区被禁止读取,回车留在缓冲区。
  • 结束条件:回车、到达size-1长度(最后一个字符存结束符)。
  • $\star$ 读取结束后不会删除缓存区中的换行符。
  • $\star$ 超出size-1长度的字符留在缓冲区,供下一次读取。
  • 只能将字符串读入C风格的字符串中,即char*。

cin.get(arrayname,size,s)

s为结束符,cin.get(arrayname,size) 缺省结束符为换行符。其余用法和 cin.get(arrayname,size) 均一样。

cin.getline

无读取单个字符的形式

cin.getline(arrayname,size)

  • 读取:从输入缓存中直接读取(若输入缓存无字符,则要求用户输入)。
  • 若缓存首部为空格、换行,则直接读取。
  • $\star$ 若缓存首部为换行符,则将 '\0' 赋给目标,将换行符删除,结束此次读取。
  • 结束条件:回车、到达size-1长度(最后一个字符存结束符)。
  • $\star$ 读取结束后会删除缓存区中的换行符。
  • $\star$ 超出size-1长度,则设置失效位failbit,阻断cin流,缓冲区被禁止读取。
  • 只能将字符串读入C风格的字符串中,即char*。

cin.getline(arrayname,size,s)

s为结束符,cin.getline(arrayname,size) 缺省结束符为换行符。其余用法和 cin.getline(arrayname,size) 均一样。

getline(推荐!)

getline(cin, str)

  • cin.getline()属于istream流,只能读入char*类型中。而getline(cin, str)属于string流,可以读入string类型中。
  • cin与getline不能连用。因为cin会将 '\n' 留在缓冲区中,getline(cin, str) 遇到 '\n' 会直接返回。因此需要在cin>> 后加上cin.ignore()取出换行符。

cin.ignore

cin.ignore(size,s)

舍弃缓冲区中的长度为size或字符s之前的数据。

cin.ignore()

缺省时size=1, s=EOF(文件结束符)。常用来防止接收上次输入的回车符。

cin.ignore(std::numeric_limits< streamsize >::max(), '\n')

其中,numeric_limits::max()是头文件定义的流使用的最大值,也可以用一个足够大的整数代替。

常用来清除输入缓冲区的所有内容,使上次的输入残留下的数据不要影响到下一次的输入。不要使用cin.sync(),sync()原意是同步输入流,而不是清空缓冲区,在不同编译器里的实现可能不同,linux下g++就无法实现。

加'\n'为清除缓冲区中一行,但缓冲区中可能不止有一行。不加'\n'为清除EOF前所有的数据,但必须要确保缓冲区中有EOF符号,否则就会一直阻塞。

cin.clear

cin.clear() 将流cin中的所有状态值都重设为有效状态。

常用cin.clear() + cin.ignore(std::numeric_limits< streamsize >::max(), '\n') 清空缓冲数据。

三、输出(cout、cerr、clog)

cout

标准输出。有缓冲。

cout<<

表示输出到缓冲区,并不是直接输出到console。而是遇到endl和flush之类的才输出。

endl、flush 和 \n

  • endl: 换行+刷新输出缓冲
  • \n: 换行
  • flush: 刷新

由于输出缓冲区为行缓冲,遇到换行符自动换行。因此 endl 和 \n 在使用上没有什么区别。若在 cout 后三者都不加,则不会输出到console,直到后面程序刷新缓冲区或程序结束。

cerr

没有缓冲,发送给它的内容立即被输出。

clog

有缓冲。

上一篇:javascript – 从字符串中获取keyCode?


下一篇:CF196A Lexicographically Maxim