0

I'm trying to use strtoul() to convert an Arduino String to an unsigned long (like the return of millis();) using the following code snippet:

unsigned long foo (String time)
{
  unsigned long mili;
  char Tim[9]="";
  uint16_t timsize = time.length()+1;
  char TIM[timsize];
  time.toCharArray(TIM,timsize);
  mili=strtoul(TIM,timsize,10);
  return mili;
}

The code seems to work. However, I'm getting the following warning:

invalid conversion from 'uint16_t {aka unsigned int}' to 'char**' [-fpermissive] mili=strtoul(TIM,timsize,10);


My question is twofold:

  1. Is there a better way to convert a String to unsigned long without first converting to a C string?

  2. If not, how can I eliminate this error?

  • unsigned long strtoul(const char *str, char **str_end, int base ); The 2nd parameter is char **. Can be nullptr. – Johnny Mopp Sep 18 '17 at 13:13
  • I believe that char TIM[timsize] is bad code. The size of arrays need to be know at compile time and since the value of time is not constant its length can't be known. I think you'd need to do a new, if you were still doing it which you aren't because you are using .c_str() – Code Gorilla Sep 18 '17 at 13:30
  • It may be poor code. I do know that it works though (however for a 2D or greater array, only the last value can be a var) – ATE-ENGE Sep 18 '17 at 13:40
  • 1
    @CodeGorilla char TIM[timsize] usually works on newer compilers: Declaring an array with a non-constant size variable – KIIV Sep 18 '17 at 13:51
  • VLAs are not part of the C++ standard. They work here because of a compiler extension. – Johnny Mopp Sep 18 '17 at 14:01
4

Arduino String class provides method c_str(). So you don't have to convert it to C string, as it's already stored as a C string internally.

And as mentioned in comments, the second parameter of strtoul is:

endptr
Reference to an object of type char*, whose value is set by the function to the next character in str after the numerical value.
This parameter can also be a null pointer, in which case it is not used.

Basically you can reduce whole foo to the: return strtoul(time.c_str(), NULL, 10);

  • Can you tell me more about how to access the c_str() method of a String? just using sec=strtoul(tim,endptr,10); did not work. – ATE-ENGE Sep 18 '17 at 13:25
  • @ATE-ENGE Added to the answer. – KIIV Sep 18 '17 at 13:29
  • 2
    Also be aware that strtol() can return 0 or ULONG_MAX if there is a problem, so the calling function should check for these because if you do a delay(ULONG_MAX); you'll think it has locked up :) – Code Gorilla Sep 18 '17 at 13:33
  • @CodeGorilla That would be a problem! Hypothetically, is there a good way to differentiate if a problem occurs? You know, in case a user actually does want to halt the program for 50 days :) – ATE-ENGE Sep 18 '17 at 13:37
  • 1
    @ATE-ENGE You can use that endptr to check if whole string was parsed. However it returns 0 if there is nothing to parse and ULONG_MAX if the value is out of range so it must be even bigger than 32bit number. – KIIV Sep 18 '17 at 13:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.