如何在C++中检查科学计数法的双精度数

3

我主要想检查一行文本是否为有效的科学计数法浮点数。

如果一行文本中含有像a这样的字符,或者只有像help0.a这样很少的字符,则会被视为无效的科学计数法浮点数并被拒绝,但是像1.234E+92.468E9这样的值将被存储,因为它是可以接受的。

我已经编写了一些代码来处理这个问题,但是我需要一些帮助来区分科学计数法浮点数和普通文本字符。

char *temp;
int u=0;
int arrayLen = strlen(temp);
for(int i=0; i<len; i++)
{
  if(isalpha(temp[i]))
  {
    if((temp[i] == 'e') && (!isalpha(temp[i-1])))
    {
      break;
    }
    u++;
  }
}

if(u > 0)
{
   temp[0] = 0;
   break;
}

3
请使用 std::stod 或其 C 语言等效函数 strtod - T.C.
3
你能使用正则表达式吗?这是一个一行就能搞定的操作。 - UniversE
@T.C. 呃 - 或者只是那 咳嗽 太棒了。太简单了。:-D - UniversE
1
使用std::istringstream和适当的I/O操纵符怎么样? - πάντα ῥεῖ
如果你得到了"1234.45E2text",你想要"1234.45E2"还是"0"? - George Houpis
显示剩余3条评论
1个回答

2
正如T.C.建议的那样,使用strtod函数。但要检查返回指针以查看它是否读取了所有内容。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

double convert_number( const char * num )
{
   char * endptr = 0;
   double retval;
   retval = strtod( num, &endptr );
   return ( !endptr || ( *endptr != '\0' ) ) ? 0 : retval;
}


int main( int argc, char ** argv )
{
    int index;
    for( index = 0; index < argc; ++index )
        printf( "%30s --> %f\n", argv[index], convert_number( argv[index] ) );
    return 0;
}

例子:

./a.out 13.2425 99993.3131.1134  13111.34e313e2  1313e4 1 324.3 "2242e+3"
                       ./a.out --> 0.000000
                       13.2425 --> 13.242500
               99993.3131.1134 --> 0.000000
                13111.34e313e2 --> 0.000000
                        1313e4 --> 13130000.000000
                             1 --> 1.000000
                         324.3 --> 324.300000
                       2242e+3 --> 2242000.000000

--------------------按请求的替代方案-----------------------------

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int convert_number( const char * num, double * retval )
{
   char * endptr = 0;
   *retval = strtod( num, &endptr );
   return ( !endptr || ( *endptr != '\0' ) ) ? 0 : 1;
}


int main( int argc, char ** argv )
{
    int index;
    double dvalue;
    for( index = 0; index < argc; ++index )
        if( convert_number( argv[index], &dvalue ) )
            printf( "%30s --> %f\n", argv[index], dvalue );
        else
            printf( "%30s --> Rejected\n", argv[index], dvalue );
    return 0;
}

结果:

./a.out 13.2425 99993.3131.1134  13111.34e313e2  1313e4 1 324.3 "2242e+3" 0.0
                       ./a.out --> Rejected
                       13.2425 --> 13.242500
               99993.3131.1134 --> Rejected
                13111.34e313e2 --> Rejected
                        1313e4 --> 13130000.000000
                             1 --> 1.000000
                         324.3 --> 324.300000
                       2242e+3 --> 2242000.000000
                           0.0 --> 0.000000

新手版:

int convert_number( const char * num, double * retval )
{
   char * endptr = 0; /* Prepare a pointer for strtod to inform us where it ended extracting the double from the string. */
   *retval = strtod( num, &endptr );  /* Run the extraction of the double from the source string (num) and give us the value so we can store it in the address given by the caller (retain the position in the string where strtod stopped processing). */
   if( endptr == NULL )
       return 0;  /* endptr should never be NULL, but it is a defensive programming to prevent dereferencing null in the next statement. */
   else if( *endptr != '\0 ) /* If we are pointing to a non-null character, then there was an invalid character that strtod did not accept and stopped processing.  So it is not only a double on the line.  So we reject. */
       return 0; /* Not strictly the double we are looking for. */ 
   /* else */
   return 1;  /* Return 1 to the caller to indicate truth (non-zero) that the value in *retval has valid double value to use. */
}

谢谢,我在想,有没有一种方法可以拒绝字符,因为0.0是一个有效的双精度浮点数。目前,该字符串被转换为双精度浮点数,得到了0.000,这是有效的,但实际上不应该这样。 - Rews Prog
请更详细地解释您的标准。您是说0.0不是有效的双精度浮点数吗? - George Houpis
谢谢你的答复。基本上,我想存储像 0.0 这样的双精度浮点数,而不是像 a./a.out 这样的字符。问题在于这些字符被转换为双精度浮点数并产生了 0.00000,因此它们变成了有效的双精度浮点数。总之,我不想读取任何字符并存储它们。我希望程序能够立即识别它们是字符,而不是有效的科学计数法双精度浮点数或仅仅是双精度浮点数。 - Rews Prog
请问您是否可以修改您的代码,如果您不介意的话。我还不太明白,但我只想拒绝那些不被视为“double”或“scientific notation double”的字符或其他内容。 - Rews Prog
如果[(endptr不为null /主要是为了防止在下一个子句中解除引用空指针/ )或者(endptr没有指向源代码行的结尾(即空终止符))],则返回0 ==> FALSE,否则返回1 ==> NOT 0也就是NOT FALSE也就是TRUE。 - George Houpis
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接