C++ 验证C+中的浮点+;没有专门的图书馆
我知道以前有人问过这个问题,但答案并没有解决我的问题,因此我提出了这个问题 我有一个简单的程序来找到三个数字中最大的一个,它应该只接受浮点数。如果输入了字符或字符串,则需要显示错误,用户需要再次输入 我有一个函数来获取有效的浮点输入C++ 验证C+中的浮点+;没有专门的图书馆,c++,floating,C++,Floating,我知道以前有人问过这个问题,但答案并没有解决我的问题,因此我提出了这个问题 我有一个简单的程序来找到三个数字中最大的一个,它应该只接受浮点数。如果输入了字符或字符串,则需要显示错误,用户需要再次输入 我有一个函数来获取有效的浮点输入 float validInput() { float x; cout<< flush; cin >> x; while(cin.fail()) {
float validInput()
{
float x;
cout<< flush;
cin >> x;
while(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout << "Not a numeric value please enter again\n";
cin >> x;
}
return x;
}
此方法适用于大多数输入。当我输入一个数字后跟一个字符时,validInput函数会异常失败。在提供此类输入时,它会显示错误消息“不是数值,请再次输入”,但不会接受其他输入,而是将字符前的数值视为输入并存储。我的要求是忽略整个输入并请求新的输入
据我了解
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cin.ignore(数值限制::max(),'\n');
不忽略输入开头输入的数字,但仅清除流中的字符,即使cin.fail()为true
有办法解决这个问题吗?cin可能需要不同的参数。但不确定
提前谢谢
资料来源:
PS:我不能使用任何像boost这样的特殊库。该代码用于实现软件测试的测试用例,因此它需要正确处理任何类型的输入。将从流中顺序读取,因此如果第一个字符表示有效的数字,它认为这是可以的。如果您想确保您读取的内容确实只是一个数字(后面没有其他字符),一个选项是使用将读取为,然后使用(C++11)将字符串转换为浮点。后者将指向无法转换的第一个字符位置的指针作为第二个参数。如果该位置小于字符串的长度,则行中包含的不仅仅是数字,因此输入无效
例如:
#include <iostream>
int main()
{
float x;
std::size_t pos;
std::string str;
while (std::getline(std::cin, str))
{
try
{
x = std::stof(str, &pos);
}
catch(...)
{
std::cout << "Not a numeric value please enter again\n";
continue;
}
if(pos != str.length())
{
std::cout << "Not a numeric value please enter again\n";
continue;
}
break;
}
std::cout << x;
}
#包括
int main()
{
浮动x;
标准:尺寸和位置;
std::字符串str;
while(std::getline(std::cin,str))
{
尝试
{
x=std::stof(str和pos);
}
捕获(…)
{
std::cout您可能想看看实际发生了什么,因为这种行为一点也不奇怪:当您在一行上输入一个浮点数,后跟一个非数字时,浮点值被提取出来就可以了。validInput()的失败案例
函数是而不是命中-通过该调用!但是,由于在再次调用函数时存在无法解析为浮点数的内容,因此第二次调用会触发失败
通过在validInput()
调用之间添加输出,您可以看到这确实是一种行为。通过这种方式,您可以判断哪些调用实际产生了错误。在没有错误时存储值是预期行为
您可以通过读取一行并验证是否可以从该行读取,以及该行上是否只有空格,来确保该行不包含无效输入。例如:
float validInput()
{
float x;
// cout<< flush; There is *NO* reason to flush cout: it is flushed when using cin
for (std::string line; std::getline(std::cin, line); ) {
std::istringstream lin(line);
if (lin >> x && (lin >> std::ws).eof()) {
break;
}
cout << "Not a numeric value please enter again\n";
}
throw std::runtime_error("reached end of input before getting a valid value!");
return x;
}
float validInput()
{
浮动x;
//cout>x&(lin>>std::ws.eof()){
打破
}
cout>std::ws
跳过此行上所有可能的尾随空格(换行符已被std::getline()
删除)。之后,应该使用流,如果确实没有进一步的输入,则设置eof()
标志(这是eof()
的少数有效用法之一).很有意义。但在按下enter键时抛出运行时错误的任何数字输入后,代码似乎不起作用,在注释掉行throw std::runtime\u error
时,代码起作用,但显示“不是数字值,请再次输入”在接受输入之前。我想这是因为在这个浮动输入之前还有其他输入。返回x;
可能应该用返回x;
替换中断
@vsoftco将中断
替换为返回x;
修复了错误,谢谢。但是当这个函数是第一个被调用时工作正常。但是当我其他std::cin
语句在调用此函数之前,它会打印“不是一个数值,请再次输入”,然后进行输入。在抛出'std::invalid_argument'what():stof中止(内核转储)的实例后,输入字符terminate调用时出现此错误
我做错了什么吗?@ShoaibAhmed否,这意味着初始字符串根本无法转换,例如,以字符开头。您可以用try/catch
块将行x=std::stof…
包围起来。请参阅更新的编辑。
float validInput()
{
float x;
// cout<< flush; There is *NO* reason to flush cout: it is flushed when using cin
for (std::string line; std::getline(std::cin, line); ) {
std::istringstream lin(line);
if (lin >> x && (lin >> std::ws).eof()) {
break;
}
cout << "Not a numeric value please enter again\n";
}
throw std::runtime_error("reached end of input before getting a valid value!");
return x;
}