C++ 获取线 CIN 错误

c++ getline cin error

本文关键字:错误 CIN 获取 C++      更新时间:2023-10-16
#include <iostream>
#include <string>
using namespace std;
int main(){
    int a1,a2,a3,a4;
cin>>a1>>a2>>a3>>a4;
string a;
getline(cin,a);
return 0;}

我有这个代码。我无法输入"a"的值。请帮帮我

您可以使用

std::ws从输入流中丢弃前导空格。

#include <iostream>
#include <string>
int main()
{
  int a1, a2, a3, a4;
  std::cin >> a1 >> a2 >> a3 >> a4;
  std::string a;
  std::getline(std::cin >> std::ws, a);
  return 0;
}

cin实际上将整数和'n'存储在输入缓冲区中。

因此,当流到达getline语句时,它只会得到一个'n'


无论如何,直接读取数字是有问题的:当cin显示它无法处理的输入时,它会进入失败状态。

它无法处理的输入将保留在输入流上并被忽略,直到清除"失败"状态(std::cin.clear())。

所以你应该检查并查看输入流是否无效(!std::cin):

std::cin >> a1;
if (!std::cin)
{    
  std::cin.clear();
  std::cin.ignore(std::numeric_limits<streamsize>::max(),'n');
  // Get the input again / handle the error
}

cppreference.com 这样的优秀文档非常清楚地解释了这个问题:

当在空格分隔的输入之后立即使用时,例如在int n; std::cin >> n;之后,getline消耗留在 输入流按 operator>> ,并立即返回。

不过,我想提出一个替代解决方案,而不是忽略剩余字符。您通常应该考虑一种编程风格,其中所有输入都是基于行的,带有std::getline .然后,如果需要,可以使用std::istringstreamstd::stoi等工具对单个行进行标记。这允许您以比通过 std::cin 的状态标志更容易的方式实现错误输入的错误处理。

例如,在

下面的示例程序中,当您尝试在第一行中输入少于或超过 4 个整数时,或者如果其中一个整数无法解析为整数,则会收到一条确切的错误消息。重要的一点是,不是使用 std::cin 直接获取整数值,而是首先接收完整的std::string行,然后拆分和分析该行。

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <stdexcept>
#include <exception>
// using just one of the many possible ways in C++ to tokenise a string:
std::vector<std::string> tokenise(std::string const& line)
{
    std::vector<std::string> tokens;
    std::istringstream is(line);
    std::string token;
    while (std::getline(is, token, ' '))
    {
        tokens.push_back(token);
    }
    return tokens;
}
std::vector<int> parse_four_integers(std::string const& line)
{
    auto const tokens = tokenise(line);
    if (tokens.size() != 4)
    {
        throw std::runtime_error("illegal token count: " + std::to_string(tokens.size()));
    }
    std::vector<int> result;
    for (auto&& token : tokens)
    {
        try
        {
            result.push_back(std::stoi(token));
        }
        catch (std::exception const&)
        {
            throw std::runtime_error("token " + token + " is not a valid integer");
        }
    }
    return result;
}
int main()
{
    try
    {
        std::string line;
        std::getline(std::cin, line);
        auto const four_integers = parse_four_integers(line);
        std::getline(std::cin, line);
        for (auto&& integer : four_integers)
        {
            std::cout << integer << "n";
        }
        std::cout << line << "n";
    }
    catch (std::exception const& exc)
    {
        std::cerr << exc.what() << "n";
    }
}