std::getline(std::cin, string) 可能因键盘输入失败的方式
Ways std::getline(std::cin, string) can fail from keyboard input
我正在编写此函数以请求特定的输入类型。 is_type只是验证收到的字符串是否可以使用 stringstream 转换为所需的类型。
template<typename T>
T get_type(std::string prompt)
{
T output;
std::cout << prompt;
std::string Input;
while (std::getline(std::cin, Input) && !is_type<T>(Input))
{
std::cout << "Invalid input type. Please try again:n"
<< prompt;
}
std::stringstream(Input) >> output;
return output;
}
这些功能似乎可以按预期工作,例如,当我键入 ctrl + Z 时除外。处理这个问题的适当方法是什么?
我补充说:
template<typename T>
T get_type(std::string prompt)
{
T output;
std::cout << prompt;
std::string Input;
while (std::getline(std::cin, Input) && !is_type<T>(Input))
{
std::cout << "Invalid input type. Please try again:n"
<< prompt;
}
if (!std::cin)
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
output = get_type<std::string>(prompt) ;
return output;
}
std::stringstream(Input) >> output;
return output;
}
在例如 ctrl+Z 之后再次要求输入这是否解决了我在用户输入下 std::getline(std::cin, std::string( 失败的问题?
另外,为什么我必须按回车键 2 次才能
output = get_type<std::string>(prompt) ;
在 if 内运行的行。
如果您以前使用过stdin
而没有清除故障位并且输入超过std::string::max_size
,则std::getline
可能会失败(请参阅Davis Herring的评论(。否则,我知道除了EOF(^Z/^D
(之外,没有办法让std::getline
失败。
但是,这是您的代码,其中包含一些小的改进:
template<typename T>
T get_type(std::string prompt)
{
T output;
std::string input;
while(true)
{
std::cout << prompt;
std::getline(std::cin, input);
std::istringstream iss(input);
if(!std::cin)
{
std::cin.clear();
// std::clearerr(stdin);
}
else if(iss >> output && iss.eof())
return output;
std::cout << "Invalid input type. Please try again:n";
}
}
如评论中所述,有必要在某些系统上stdin
上使用clearerr
。如果您的系统需要,只需取消注释std::clearerr(stdin);
。
由于您的 2 倍<Enter>
问题:忽略语句是不必要的。您只需忽略下一个输入(这就是为什么您必须点击两次<Enter>
(。
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 物理键盘上的触发器按键
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 使用一个考虑到std::map中键值的滚动或换行的键
- 如何使 std::istream 从键盘获取输入(如 std::cin)?
- std::getline(std::cin, string) 可能因键盘输入失败的方式
- 如何在使用管道后将std::cin恢复到键盘上