我遇到了一个我正在使用C ++编写的程序的问题。我要求用户输入有效的号码。我把它作为一个字符串,因为我正在做的特定任务,从长远来看它使它更容易。对于基本错误检查,我想检查输入的数字是否是有效数字。例如:
Enter number: 3.14
This would be valid
Enter number: 3.1456.365.12
This shouldn't be valid
答案 0 :(得分:9)
使用strtod,它将字符串转换为double并返回任何不能解释为double的字符的字符。
double strtod(const char* nptr, char** endptr)
像这样:
char* input = "3.1456.365.12";
char* end;
strtod(input, &end);
if (*input == '\0')
{
printf("fail due to empty string\n");
}
if (end == input || *end != '\0')
{
printf("fail - the following characters are not part of a double\n%s\n", end);
}
答案 1 :(得分:7)
我认为boost :: lexical_cast可以帮助你
答案 2 :(得分:4)
仅使用标准C ++的示例:
#include <sstream>
// ...
double dbl = 0.0;
std::istringstream num("3.1456.365.12");
num >> dbl;
if(!num.fail() &&
num.eof()) // This second test is important! This makes sure that the entire string was converted to a number
{
// success
}
else
{
// failure
}
奖金通用模板功能版本:
#include <sstream>
#include <string>
#include <exception>
// Version that throws an exception on a bad parse:
template <typename T>
T parse(const std::string& str)
{
T value;
std::istringstream parser(str);
parser >> value;
if(!parser.fail() && parser.eof())
{
return value;
}
else
{
throw "bad lexical cast";
}
}
// usage:
double foo = parse<double>("3.14234");
// Non-exception, error code version
template <typename T>
bool parse(const std::string& str, T& value)
{
std::istringstream parser(str);
parser >> value;
return (!parser.fail() && parser.eof());
}
// usage:
double foo = 0.0;
bool success = parser<double>("3.11234", foo);
答案 3 :(得分:3)
如果您没有提升,则始终可以使用strtod
答案 4 :(得分:3)
您可以使用strtoX
(其中X为f
表示浮动,l
表示长,ul
表示无符号长整数等。),选择数字类型你要。你给它的一个参数是一个“结束指针”,它指向字符串中第一个可以不转换为目标数字类型的字符。
在你的情况下,你正在寻找的是结束指针应该在字符串的末尾,表明字符串中的所有字符都被转换为目标类型。
编辑:对不起,没有注意到你在标题中提到了'double'(但不是问题本身)。在这种情况下,你会使用strtod
,因为其他几个人也建议。
答案 5 :(得分:2)
最好的方法是使用任何标准和/或惯用的方式进行实际尝试将您的字符串转换为double
,然后检查错误。在C中,它将是来自strto...
组的函数(当然,它们在C ++中也是完全可用的)。在C ++中,您可以使用基于流的转换习惯用法。
值得注意的一点是,标准转换方法中的常见惯例是“尽可能”地转换,而不是将任何额外的字符视为错误。例如,字符串“123abc”通常被认为是有效输入,只有“123”部分被转换。如果您希望将此情况视为错误,则所有可用的方法都为您提供了检测实际数字后面还有其他内容的方法。但是您可以采取额外的步骤来执行此验证。
答案 6 :(得分:1)
一个简单的选择是使用sscanf函数:
const char * num_as_str = "3.1416";
double num;
if(std::sscanf(num_as_str, "%lg", &num) == 1)
{
std::cout << "You correctly entered the number " << num << "\n";
}
如果你想获得幻想,你可以使用istringstream:
std::istringstream iss(num_as_str);
if(iss >> num)
{
std::cout << "You correctly entered the number " << num << "\n";
}
如果你想获得额外的幻想,你可以使用boost的lexical_cast:
try
{
num = boost::lexical_cast<double>(num_as_str);
}
catch(boost::bad_lexical_cast &)
{
std::cout << "What you entered is not a proper number" << num << "\n";
}
答案 7 :(得分:0)
boost
)。它们快速,易于编写并且非常有趣。如果你能在Lex / Yacc上获得Levine的书的副本,请查看前几章的想法。
答案 8 :(得分:0)
正如AndreyT所提到的,最好的方法是尝试将字符串转换为浮点数并检查错误。我个人会选择使用std :: istringstream,因为你正在使用C ++。以下内容应该有效:
float ff;
std::istringstream istr;
std::string input("1234.5678");
// set the stream to have your string as its base
istr.str(input);
// now try to read the number:
istr >> ff;
if (istr.fail())
{
// some error in the parsing
}
istringstream是STL的一部分,所以你不需要任何额外的库,如果你选择它也会有异常。可以在此处找到更多信息:http://www.cplusplus.com/reference/iostream/istringstream/
答案 9 :(得分:0)
答案 10 :(得分:0)
这是我的快速黑客:)
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
template <typename T>
bool fromStr(const std::string& str, T& var)
{
std::stringstream convertor;
convertor << str;
convertor >> var;
if( convertor.fail() )
return false;
char c = static_cast<char>( convertor.get() );
return convertor.eof() || c == '\n' || c == ' ' || c == '\t';
}
int main()
{
double d;
std::string str = "5.04146.55";
if( fromStr<double>(str, d) )
{
std::cout << "Valid conversion!, d = " << d;
}
else
{
std::cout << "Invalid conversion!";
}
}