如何确保我有双倍而不是其他东西?
int main() {
int flagOk = 0;
double number;
while(!flagOk) {
printf("Put in a double");
scanf("%lf", &number);
if(number == "%lf"); //this want make sure
flagOk = 1;
}
}
答案 0 :(得分:8)
检查scanf()
的返回值;它告诉你有多少次转换是成功的。
在上下文中,如果转换失败,则得到0;如果成功,你得到1。
需要考虑错误恢复。我通常会发现使用fgets()
(和never gets()!)更容易阅读一行数据,然后使用sscanf()
处理它。如果转换失败,很容易丢弃错误的数据。
答案 1 :(得分:3)
如果你想确保用户期望的值与通过将字符串传递给 atof(str) - 包括指数表示法所返回的值一致 - 那么以下代码有效。
您可以使用 fgets(str,size,stdin)获取输入,甚至在将字符串传递给解析器之前甚至不必删除尾随换行符。
此外,如果存在解析错误,该函数会将可犯罪字符的位置报告给作为附加参数传递的指针。
有一个很长的形式 - 更容易阅读,简短的形式 - 更容易输入。
长篇:
/*
Copyright (C) 2010 S. Randall Sawyer
This code is in the public domain. It is intended to be usefully illustrative.
It is not intended to be used for any particular application. If this code is
used in any application - whether open source or proprietary, then please give
credit to the author.
*/
#include <ctype.h>
#define FAILURE (0)
#define SUCCESS (!FAILURE)
enum {
END_EXPRESSION = 0x00,
ALLOW_POINT = 0x01,
ALLOW_NEGATIVE = 0x02,
REQUIRE_DIGIT = 0x04,
ALLOW_EXPONENT = 0x08,
HAVE_EXPONENT = 0x10,
EXPECT_EXPRESSION = ALLOW_POINT | ALLOW_NEGATIVE | REQUIRE_DIGIT,
EXPECT_INTEGER = ~ALLOW_POINT,
EXPECT_POS_EXPRESSION = ~ALLOW_NEGATIVE,
EXPECT_POS_INTEGER = EXPECT_INTEGER & EXPECT_POS_EXPRESSION,
EXPECT_EXPONENT = EXPECT_INTEGER ^ HAVE_EXPONENT,
EXPONENT_FLAGS = REQUIRE_DIGIT | ALLOW_EXPONENT | HAVE_EXPONENT
} DoubleParseFlag;
int double_parse_long ( const char * str, const char ** err_ptr )
{
int ret_val, flags;
const char * ptr;
flags = EXPECT_EXPRESSION;
ptr = str;
do {
if ( isdigit ( *ptr ) ) {
ret_val = SUCCESS;
/* The '+' here is the key: It toggles 'ALLOW_EXPONENT' and
'HAVE_EXPONENT' successively */
flags = ( flags + ( flags & REQUIRE_DIGIT ) ) & EXPECT_POS_EXPRESSION;
}
else if ( (*ptr & 0x5f) == 'E' ) {
ret_val = ( ( flags & ( EXPONENT_FLAGS ) ) == ALLOW_EXPONENT );
flags = EXPECT_EXPONENT;
}
else if ( *ptr == '.' ) {
ret_val = ( flags & ALLOW_POINT );
flags = ( flags & EXPECT_POS_INTEGER );
}
else if ( *ptr == '-' ) {
ret_val = ( flags & ALLOW_NEGATIVE );
flags = ( flags & EXPECT_POS_EXPRESSION );
}
else if ( iscntrl ( *ptr ) ) {
ret_val = !( flags & REQUIRE_DIGIT );
flags = END_EXPRESSION;
}
else {
ret_val = FAILURE;
flags = END_EXPRESSION;
}
ptr++;
} while (ret_val && flags);
if (err_ptr != NULL)
*err_ptr = ptr - 1;
return ret_val;
}
简短形式:
/*
Copyright (C) 2010 S. Randall Sawyer
This code is in the public domain. It is intended to be usefully illustrative.
It is not intended to be used for any particular application. If this code is
used in any application - whether open source or proprietary, then please give
credit to the author.
*/
#include <ctype.h>
int double_parse_short ( const char * str, const char ** err_ptr )
{
int ret_val, flags;
const char * ptr;
flags = 0x07;
ptr = str;
do {
ret_val = ( iscntrl ( *ptr ) ) ? !(flags & 0x04) : (
( *ptr == '.' ) ? flags & 0x01 : (
( *ptr == '-' ) ? flags & 0x02 : (
( (*ptr & 0x5f) == 'E' ) ? ((flags & 0x1c) == 0x08) : (
( isdigit ( *ptr ) ) ? 1 : 0 ) ) ) );
flags = ( isdigit ( *ptr ) ) ?
(flags + (flags & 0x04)) & 0x1d : (
( (*ptr & 0x5f) == 'E' ) ? 0x0e : (
( *ptr == '-' ) ? flags & 0x1d : (
( *ptr == '.' ) ? flags & 0x1c : 0 ) ) );
ptr++;
} while (ret_val && flags);
if (err_ptr != NULL)
*err_ptr = ptr - 1;
return ret_val;
}
我希望这有帮助!
答案 2 :(得分:2)
你可能想要一个更像这样的代码片段:
double number;
do {
printf("Enter a double: ");
scanf("%*c"); // burn stdin so as not to buffer up responses
} while (1 != scanf("%lf", &number));
然而正如Jonathan所指出的,一些更好的逐行解析可能会更好。直接从stdin
以这种方式扫描对用户来说并不直观。