简体   繁体   中英

Problem with string conversion to number ( strtod )

I am using strtod( ) function to extract an environment variable as a string, and then changing it to double using 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);

Now i want to make sure that this number entered by user is a number and not a string or special character. How can i make sure of that?

A code snippet would be of great help.

Thanks in advance.

The 2nd argument to the strtod function is useful.

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

Edit: examples added

The strtod function tries to convert the initial portion of the 1st argument to a double and stops either when there are no more chars, or there is a char that can't be used to make a double.

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 == ' ')

Surely you could do worse than just reading the man page for strtod() and acting upon that. Eg on my Linux system it says:

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.

That pretty much tells you what you need to do in order to handle errors. Also, like Johann Gerell said, you also need to check whether getenv() succeeded; a similar approach works there, ie check the man page and write error handling code according to that.

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

char * endptr;
double d = strtod(strEnv, &endptr);
if (strEnv == endptr)
   /* invalid number */
else
   ...
  • First, check the return value of getenv - if it's NULL, then that environment variable doesn't exist.
  • Second, if the return value of getenv isn't NULL, then you have the value, as a string.
  • Third, don't set the char ** endptr parameter of strtod to NULL, but use it to check the validity of the converted value, also check for 0.0 .

That second argument to strtod , which you've set to NULL , can be a pointer-to-pointer-to-char; the pointer-to-char that it points to will get set to the character after the last thing strtod managed to parse. If that's the end of the string, or at least there's nothing after it but whitespace, then what you had was a number. Otherwise, it was something else.

I don't know much about this language but I do know that strtod() will return 0.0 if the input is wrong. Maybe you could use a regular expression to validate the input string is a number.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM