How to detect conversion error in strtod()?

I'm having a bit of weird trouble with the strtod() function. The Man page examples I've found (linux.die.net/man/3/strtol) suggest it should be used like this:

errno = 0;    /* To distinguish success/failure after call */
val = strtol(str, &endptr, base);
/* Check for various possible errors */
if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
  || (errno != 0 && val == 0)) {
  // handle error
}

..however, the Arduino doesn't seem to have 'errno' (or if it does, I don't know how to use it!?). Also, this doesn't work:

if((val = strtod(str,NULL)) == NULL) {
  // handle error
}

(no where I can find says it does, but if you've used strtol() you might think it should).

So... The real question is how can I detect an actual error in strtod()? So far, something like:

val = strtod("hello",NULL);

...just sets val = 0.0 (which isn't really correct). I can use this as it is, but I can make usability considerably better if I can actually detect the error. Any ideas?

Perhaps you should be using sscanf, instead. It does the conversion from string to long, int, double, float, string, char, etc. It returns the number of tokens successfully extracted from the string.

So, if your string is supposed to contain just one double, sscanf will return 1 if the string really did contain a double (as well as the double), or 0 if the string did NOT contain a double.

coofercat,

If you put this line at the top of your sketch:#include <errno.h>It will define ‘errno’, ‘EDOM’, and ‘ERANGE’.

Regards,

-Mike

Thank you both for great answers - I can’t believe I didn’t spot the #include solution (it seems my C/C++ knowledge is dustier than I thought!). I’ll also look at sscanf.

Cheers!

So, if your string is supposed to contain just one double, sscanf will return 1 if the string really did contain a double (as well as the double), or 0 if the string did NOT contain a double

Actually it will not - The AVR/Arduino library does not include support for "%f" formatting.

Thanks again.

I’m also not sure the arduino set errno. Thanks to Mike, I’ve got errno in scope now, but it’s not set. This code doesn’t seem to work:

#include <errno.h>
double val;
char *s;
errno = 0;
val = strtod("hello", &s);
if(errno) {
  Serial.print("Conversion error");
}

Can anyone help out? Is it just my, er, poor C/C++, or is it an arduino problem?

coofercat,

I should have looked at the question behind the question. After reading the documentation, I discovered that strtod() does not set errno if there is a conversion error. It only sets errno if there is an overflow or underflow during the conversion.

Conversion errors are indicated by the pointer pointed to by the second argument being set to the same value as the first argument. The second argument is used to show where the conversion left off (so you can convert multiple numbers with repeated calls to strtod()), so it makes sense that it wouldn't move if there were a conversion error.

Here's how to check for an error:

double val;
char *start;
char *end;

start = "hello";
val = strtod(start, &end);
if(end == start) {
  Serial.print("Conversion error");
}

I hope this info helps.

-Mike

Ahh... that would explain it. Thanks for spotting that for me (I can't really blame that one on my rusty C!).

That's really cool - it's working fine now - thank you so much!