Проблема с преобразованием строки в число (strtod) - PullRequest
6 голосов
/ 07 апреля 2011

Я использую функцию strtod () для извлечения переменной окружения в виде строки, а затем меняю ее на удвоенную, используя strtod:

enter code here
 char strEnv[32];
 strncpy(strEnv, getenv("LT_LEAK_START"), 31);
 // How to make sure before parsing that env LT_LEAK_START is indeed a number?
 double d = strtod(strEnv, NULL);

Теперь я хочу убедиться, что это число, введенное пользователемчисло, а не строка или специальный символ.Как я могу убедиться в этом?

Фрагмент кода будет очень полезен.

Заранее спасибо.

Ответы [ 6 ]

16 голосов
/ 07 апреля 2011

2-й аргумент функции strtod полезен.

char *err;
d = strtod(userinput, &err);
if (*err == 0) { /* very probably ok */ }
if (!isspace((unsigned char)*err)) { /* error */ }

Редактировать: примеры добавлены

Функция strtod пытается преобразовать начальную часть 1-го аргумента в двойную и останавливается, когда больше нет символов или существует символ, который не может быть использован для создания двойной переменной.

input         result
----------    ----------------------------
"42foo"       will return 42
              and leave err pointing to the "foo" (*err == 'f')

"     4.5"    will return 4.5
              and leave err pointing to the empty string (*err == 0)

"42         " will return 42
              and leave `err` pointing to the spaces (*err == ' ')
3 голосов
/ 07 апреля 2011

Конечно, вы могли бы сделать хуже, чем просто читать справочную страницу strtod () и действовать в соответствии с этим. Например. в моей системе Linux написано:

RETURN VALUE
       These functions return the converted value, if any.

       If  endptr  is  not  NULL,  a pointer to the character after the last character used in the conversion is stored in the location referenced by
       endptr.

       If no conversion is performed, zero is returned and the value of nptr is stored in the location referenced by endptr.

       If the correct value would cause overflow, plus or minus HUGE_VAL (HUGE_VALF, HUGE_VALL) is returned (according to the sign of the value), and
       ERANGE is stored in errno.  If the correct value would cause underflow, zero is returned and ERANGE is stored in errno.

Это в значительной степени говорит вам, что вам нужно сделать для обработки ошибок. Кроме того, как сказал Иоганн Герелл, вам также необходимо проверить, удалось ли getenv (); аналогичный подход работает там, то есть проверьте страницу руководства и напишите код обработки ошибок в соответствии с этим.

2 голосов
/ 07 апреля 2011

man strtod: если преобразование не выполняется, возвращается ноль и значение nptr сохраняется в местоположении, указанном в endptr.

char * endptr;
double d = strtod(strEnv, &endptr);
if (strEnv == endptr)
   /* invalid number */
else
   ...
1 голос
/ 07 апреля 2011
  • Сначала проверьте возвращаемое значение getenv - если оно равно NULL, то этой переменной среды не существует.
  • Во-вторых, если возвращаемое значение getenv не равно NULL, тогда у вас есть значение в виде строки.
  • В-третьих, не устанавливайте для параметра char ** endptr strtod значение NULL, но используйте его для проверки действительности преобразованного значения, а также для проверки0.0.
0 голосов
/ 07 апреля 2011

Я не знаю много об этом языке, но я знаю, что strtod () вернет 0.0, если ввод неправильный.Возможно, вы могли бы использовать регулярное выражение для проверки того, что входная строка представляет собой число.

0 голосов
/ 07 апреля 2011

Второй аргумент strtod, который вы установили на NULL, может быть указатель на указатель на символ;указатель на символ, на который он указывает, будет установлен на символ после того, как последнюю вещь strtod удалось проанализировать.Если это конец строки или, по крайней мере, после нее ничего нет, кроме пробела, то у вас был номер.Иначе это было что-то еще.

...