所以我使用 atof 将我的字符串转换为双精度。但我需要知道我是否输入错误(如 y564 等)。我怎样才能检查它?我需要正确的号码才能对其采取进一步行动。
double x = atof(s.c_str());
您可能想使用std::stod:
bool parse_double(std::string in, double& res) {
try {
size_t read= 0;
res = std::stod(in, &read);
if (in.size() != read)
return false;
} catch (std::invalid_argument) {
return false;
}
return true;
}
int main()
{
double d;
bool b = parse_double("123z", d);
if (b)
std::cout << d;
else
std::cout << "Wrong input";
}
[编辑]
你可以在这里找到:
返回值
成功时对应str的内容的double值。如果转换后的值超出返回类型的范围,则返回值未定义。如果不能进行转换,则返回 0.0。
这样就无法确定输入是错误的还是包含0
.
使用std::stod
. 它对无效输入抛出异常。或者,如果您坚持使用 C 解决方案,请使用strtod
; 它为您提供有关结果的更多信息。
atof 的定义(http://en.cppreference.com/w/cpp/string/byte/atof):
返回值
成功时对应str的内容的double值。如果转换后的值超出返回类型的范围,则返回值未定义。如果无法执行转换,则返回 0.0。
如果您使用现代 c++ 并且您现在必须返回,最好使用std::strtod
( http://en.cppreference.com/w/cpp/string/byte/strtof ):
double strtod( const char* str, char** str_end );
其返回值定义为:
返回值
str 的内容对应的浮点值就成功了。如果转换后的值超出相应返回类型的范围,则会发生范围错误,并返回 HUGE_VAL、HUGE_VALF 或 HUGE_VALL。如果无法进行转换,则返回0,并将 *str_end 设置为 str。
正则表达式(即libpcre)来拯救:
// checked_atof.cpp
#include <iostream>
#include <cstdlib>
#include <pcrecpp.h>
const char FP_RE[] = "^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?";
using namespace std;
int main()
{
std:string s;
double number;
pcrecpp::RE fpre(FP_RE);
cout << "Enter a floating point number: " << endl;
cin >> s;
if (!fpre.FullMatch(s)) {
cout << "Sorry, not a valid floating point number!" << endl;
} else {
number = atof(s.c_str());
cout << "Ok, result: " << number << endl;
}
return 0;
}
有关安装/编译的详细信息,请参阅libpcre
文档——以下内容可能适用于您的系统:
g++ checked_atof.cpp $(pkg-config --cflags libpcrecpp) $(pkg-config --libs libpcrecpp) -o checked_atof
$ ./checked_atof.exe
Enter a floating point number:
23.42
Ok, result: 23.42
$ ./checked_atof.exe
Enter a floating point number:
3.14159e-4
Ok, result: 0.000314159
$ ./checked_atof.exe
Enter a floating point number:
x9
Sorry, not a valid floating point number!
您可以简单地检查字符串的每个字符是否是“。” 或std::isdigit(int ch)在将其传递给 atof 之前(并且“。”必须是唯一的)
更紧凑的解决方案是使用正则表达式来处理您的字符串,该正则表达式^[0-9]+(\.[0-9]+)?$
应该适用于通用浮动值。