Я написал небольшой код, который разбивает любую строку (экспортированную как переменную среды) на целое число и дробную часть.
Пример: экспорт ENV_NUM = 3.45
Программа напечатает: целое число: 3 Дробное: 0,45
Кроме того, эта программа также сканирует, находится ли экспортированный номер вне допустимого диапазона или является недопустимым, и в этом случае она прекращает печать сообщения об ошибке.
Чтобы упростить для читателя вещи, позвольте мне объяснить логику, которую я использовал : я отсканировал число и число разбилось на 2 части, используя 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)