几种 cin 输入方式的区别

几种 cin 输入方式的区别

几种 cin 输入方式的区别#

为了描述方便, 用语约定如下:

读入从输入流中提取并使用内容, 输入流中将不再有该内容, 而该内容被实际使用.

读过从输入流中提取并忽略内容, 输入流中将不再有该内容, 而该内容被忽略.

查看查看输入流中内容, 输入流中内容不变.

输入流

通常输入区域就像管道里的水流一样, 你只能首先接触最开始的字符, 且没有回头路.

共同部分#

无论以下何种方式, 都会在到达文件尾 (eof, end of file) 时结束输入.

除 ch = cin.get() 和 ch = cin.peek() 外, 所提及的方式均返回输入流 cin 本身, 从而允许链式调用和条件判断:

链式调用#

1std::cin >> value1 >> value2;

2getline(getline(std::cin, line), line);

条件判断: cin 能够隐式类型转换为 bool 类型, 相当于表达式 !cin.fail().#

1while (std::cin >> value) {

2 /* 读取成功 */

3}

输入存在缓冲区, 当我们通过键盘或其他方式进行输入时, 程序总是将内容先填入对应的缓冲区中. cin 即从它的缓冲区中读取要求的内容:

用键盘一次性输入若干内容#

1// 直接输入: 1 2 3

2for (int value = 0; std::cin >> value;) {

3 /* 第 1 次: value == 1 */

4 /* 第 2 次: value == 2 */

5 /* 第 3 次: value == 3 */

6}

提示

你也可以通过断点调试观察这个过程, 自己验证一下结果如何. 断点调试非常有用, 请学习 断点调试的使用 并完成习题.

格式化输入#

该方式输入的字符将会格式化为对应的类型值, 例如:

1int value;

2std::cin >> value; // 读入的字符格式化为 int 类型值

cin >> value默认情况下读过前面所有空白符, 然后读入字符直到查看到空白符.

非格式化输入#

该方式输入的就是字符本身.

cin.get(ch);、ch = cin.get();读入输入流中第一个字符.

ch = cin.peek();查看输入流中第一个字符.

cin.get(char* output, streamsize count, char delim = '\n')读入字符到 output 中, 直到读入了 count - 1 个字符或查看到分隔符 delim (默认为换行符 '\n'); 若确实有读入字符, 则在之后附上终止字符 :cpp:'\0'.

cin.getline(char* output, streamsize count, char delim = '\n')读入字符到 output 中, 直到读入了 count - 1 个字符或读过了分隔符 delim; 若确实有读入字符, 则在之后附上终止字符 :cpp:'\0'.

提示

为什么是读入 count - 1 个字符? 因为这些输入方式认为输入内容将被作为一个字符串, 而字符串需要在尾部用 '\0' 表示终止, 故这些方式为 '\0' 预留一个位置.

getline(std::cin, std::string& output, char delim = '\n')读入字符到 output 中, 直到读过了分隔符 delim. 相比于上面的, 这是 推荐的方式.

cin.ignore(streamsize count, char delim)读过字符直到读过了 count 个字符或读过了分隔符 delim.

通常 #include , 然后以 std::cin.ignore(std::numeric_limits::max(), '\n') 方式使用, 表示一直读过字符直到读过换行符 '\n'.

此外, 你也可以使用 std::cin >> std::ws, 这会读过所有的空白符 (空格、制表、换行等), 直到查看到非空白符.

cin.read(char* output, streamsize count)读入 count 个字符到 output 中, 通常用于 二进制输入输出 (binary I/O).

放回输入流中#

cin.unget()将最近读入/读过的字符放回 cin 中, 相当于 cin.get() 的逆向操作.

cin.putback(char ch)将 ch 放回 cin 中, 之后通过 cin 进行输入时, 第一个字符将会是 ch.

从错误状态恢复过来#

数据读取失败后, cin 将会被设置成一个错误状态导致我们无法继续使用. 我们此时需要自己清理输入缓冲区中的残留数据 (毕竟已经出错了, 这些数据你已经不知道变成了什么样, 而且可能没用了), 并恢复 cin 的状态:

1#include

2using namespace std;

3

4cin.clear(); // 恢复状态

5cin.ignore(numeric_limits::max(), '\n'); // 清理缓冲区

当然有的状态没办法正常恢复 (一个极端的例子是突然停电了).

参见

输入失败的各种情况见于 文件读写.

最佳实践#

由于格式化输入和非格式化输入间的行为差异, 不建议混用格式化输入和非格式化输入.

如果确实需要一行行读取内容, 并在行内进行格式化输入, 可以参考以下代码:

1#include

2#include

3#include

4

5int main() {

6 std::ifstream ifile("输入文件路径");

7 std::string line;

8 while (std::getline(ifile, line)) { // ifile 输入流非格式化输入一行到 line 中

9 std::istringstream iss(line); // 将 line 中内容作为另一个输入流

10 int value = 0;

11 iss >> value; // iss 输入流进行格式化输入

12 }

13}

🎨 相关创意作品

阴阳师花舞哪里刷的多 花舞刷新点在哪里盘点
没有找到站点
365bat提现

没有找到站点

📅 07-21 👁️ 1225
如何找人查一个人?
365英国官网

如何找人查一个人?

📅 07-16 👁️ 5472