如何检查字符串是否可以转换为浮点数?

Lot*_*har 2 c floating-point type-conversion

首先,我的上下文是需要将浮点文字(字符串)转换为float/double值的编译器编写器.在过去的15年里,我没有做任何浮点编程,所以我很确定这是一个完全愚蠢的新手问题.

double res; 
errno=0; 
*res = strtod((const char*)literal,NULL); 
if (errno==ERANGE) throw_a_literal_out_of_range_exception();
return res;
Run Code Online (Sandbox Code Playgroud)

但是c运行时库中没有"strtof"函数?

编辑:澄清.我已经知道字符串'literal'是C浮点的有效模式.它已经通过了正则表达式测试.我只想检查是否存在范围/精度问题.

原因在于用户可以编写的Eiffel源代码

a := {REAL_32} 3.1415
b := {REAL_32} 3.0E200
Run Code Online (Sandbox Code Playgroud)

将写入的浮点数explit转换为32位浮点数.我认为在第二种情况下,编译器应检测到该值超出范围并引发错误或至少发出警告.

小智 9

在C89中,您可以使用sscanf.

例如:

float myfloat;

if(sscanf(str, "%f", &myfloat) != 1)
    /* String could not be converted */
else
    /* String was converted, myfloat is usable */
Run Code Online (Sandbox Code Playgroud)


jam*_*lin 6

@Nicholas Goy:我认为sscanf(str, "%f, &float) == 1(或!= 1)不会真正做到所需.

如果在str(例如"1.1foo")中有其他字符,它将无错误地解析,这可能是不合需要的.这可以通过以下方式纠正:

char dummy;
if (sscanf(str, "%f%c", &float, &dummy) != 1) {
   /* Parse error. */
} else {
   /* Parsed cleanly. */
}
Run Code Online (Sandbox Code Playgroud)

代替.然而,sscanf有%f可能使用strtod内部和投反正浮动.C标准中的语言说:

a,e,f,g匹配可选带符号的浮点数,无穷大或NaN,其格式与strtod函数的主题序列的预期格式相同.相应的参数应该是浮动的指针.

哪种意味着这一点,对我来说似乎是对的(FreeBSD上的gcc 4.2.1).使用上面的sscanf代码,"1.79e308"成功解析,但有值+ INF一样,"5E-300",其值为0.0,而这些都是你从得到相同的结果(float) 1.79e308和(float) 5e-300.

无论如何.总而言之,我质疑为什么OP想要使用float而不是double.


小智 5

我打算说,只需使用你已经拥有的代码,但是将strod()的结果赋给float而不是double.但是你的代码在几个方面都是错误的.

首先,除非出现错误,否则无法测试errno.其次,除了范围错误之外,strtod()不会设置errno.如果您传递一个无效的数字,如"XYZ",则不会设置它.

更正确地使用strtod是:

char *p;
double d = strtod( "123.4xyz", & p );
if ( * p != 0 ) {
   // not a number - in this case will point at 'x'
}
Run Code Online (Sandbox Code Playgroud)

使用strtod()来读取浮点数,你可能会失去一些精度,但这是你使用浮点数所付出的代价 - 一般来说,除非你有充分的理由不这样做,你应该总是更喜欢使用double来浮动.