乐闻世界logo
搜索文章和话题

Why does std:: getline skip input after a formatted extraction?

2 个月前提问
2 个月前修改
浏览次数24

1个答案

1

在C++标准库中,std::getline() 是用来从输入流中读取一行数据的,通常与 std::istream 类型一起使用,比如 std::cin。在使用 std::getline() 读取数据时,可能会遇到一个常见的问题:在执行格式化输入(例如使用 >> 操作符)之后,直接使用 std::getline() 会导致它跳过输入。这通常是因为格式化输入操作会留下换行符 \n 在输入缓冲区中。

解释

当你使用 >> 操作符从 std::cin 读取数据时,比如读取一个整数或字符串,输入操作会在遇到第一个空白字符(空格、换行等)时停止。这通常意味着换行符 \n,它是你按下回车键时生成的,还留在输入缓冲区中。当你之后调用 std::getline() 时,它会从当前缓冲区的位置开始读取,直到遇到下一个换行符为止。由于输入缓冲区中的第一个字符就是 \nstd::getline() 会认为这是一个空行,并立即停止读取。

示例

cpp
#include <iostream> #include <string> int main() { int number; std::string line; std::cout << "请输入一个数字:" << std::endl; std::cin >> number; // 假设输入了123并按了回车 std::cout << "请输入一个句子:" << std::endl; std::getline(std::cin, line); // 这里会直接读到一个空字符串 std::cout << "数字是:" << number << std::endl; std::cout << "句子是:" << line << std::endl; // 输出将是空的 return 0; }

解决方法

为了解决这个问题,可以在每次使用格式化输入后,使用 std::cin.ignore() 来清除输入缓冲区中的任何残留字符,特别是换行符。std::cin.ignore() 可以用来忽略缓冲区中的字符直到遇到指定的终止字符,通常是换行符。

修改后的示例:

cpp
#include <iostream> #include <string> int main() { int number; std::string line; std::cout << "请输入一个数字:" << std::endl; std::cin >> number; // 假设输入了123并按了回车 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 忽略直到遇到换行符 std::cout << "请输入一个句子:" << std::endl; std::getline(std::cin, line); std::cout << "数字是:" << number << std::endl; std::cout << "句子是:" << line << std::endl; return 0; }

这里,std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 告诉程序忽略输入流中的所有字符直到遇到一个换行符,从而确保下一次调用 std::getline() 时可以正确地读取整行数据。

2024年7月24日 11:11 回复

你的答案