gpt4 book ai didi

c - 数字解析器程序 : why strtol/strtod fails for exponential and hex numbers

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:40:01 26 4
gpt4 key购买 nike

我写了一个小代码,它将任何字符串(导出为环境变量)分成整数和小数部分。

例子: 导出 ENV_NUM=3.45

程序将打印: 整数:3 小数:0.45

此外,此程序还会扫描导出的号码是否超出范围或无效号码,在这种情况下,它会退出并打印错误消息。

为了简化读者的操作,让我解释一下我使用的逻辑: 我已经扫描了数字,并使用 strtok 在发现小数点 (.) 的地方将数字分成两部分,然后将第一个标记分配给整数部分,将下一个标记分配给小数部分。

面临的问题:现在这个程序的问题是:如果导出的数字是十六进制数或指数数,它会给出错误的结果。

你能告诉我问题是什么吗?

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


static time_t wholeNumber;
static float fractional;

void numberParser(void);

int main(int argc, char **argv)
{
numberParser( );
printf("Whole number: %12d, Fractional: %5.8f\n", wholeNumber, fractional);
return 0;
}

void numberParser( void )
{
char * charPtr, * numberFormatErr;
charPtr = getenv("ENV_NUM");

if ( charPtr == NULL )
return;

double envVal = strtod(charPtr, &numberFormatErr);

/* This part checks if the string is a valid number and not negative */

if ( (numberFormatErr == charPtr) || (*numberFormatErr != '\0') ) {
printf("exited: ENV_NUM is not a number\n");
exit(1);
}
else if ( envVal < 0 ) {
printf("exited: ENV_NUM a negative number\n");
exit(1);
}

/* This part breaks the string into integral and float part */

char * tokens = strtok(charPtr, ".");
int count = 0;
errno = 0;

while ( tokens != NULL ) {
//printf("Token scanned: %s\n",tokens);
long d = strtol(tokens, NULL, 10);
//printf("token to long: %5d\n",d);

if ( errno == ERANGE && d == LONG_MAX ) {
printf("exited: ENV_NUM not in valid range.");
exit(1);
}

if ( count == 0 ) {
( wholeNumber = d );
}

tokens = strtok(NULL, " ");
count++;
}
fractional = (envVal) - (double)(wholeNumber);
}

这是输出:

Correct output for normal numbers
[time_related]$ ./a.out
Whole number: 3, Fractional: 0.56000000

十六进制的错误输出: [time_related]$ export ENV_NUM=0x21

[time_related]$ ./a.out 
Whole number: 0, Fractional: 33.00000000 (should be 33, 0)

指数的错误输出: [time_related]$ export ENV_NUM=3e3

[time_related]$ ./a.out 
Whole number: 3, Fractional: 2997.00000000 (should be 3000, 0)

最佳答案

令我惊讶的是 strtod 解析十六进制数字,因为我查看了两个引用文献并且他们没有提到这种能力,但为什么不呢。
请注意,0x21 = 33,而不是 35。

你做了中间打印,使用它:对于 0x21,envVal 是 33,strtol 无法解析超出 x,所以它返回 0,小数是 envVal - 0 = 33
同上 3e3:它不是一个长数,所以 strtol 返回 3,小数部分是 3000-3

您应该像对 strtod 所做的那样对 strtol 的结果添加检查...

关于c - 数字解析器程序 : why strtol/strtod fails for exponential and hex numbers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7484776/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com