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?

asked Sep 18, 2017 at 13:00
5
  • unsigned long strtoul(const char *str, char **str_end, int base ); The 2nd parameter is char **. Can be nullptr. Commented Sep 18, 2017 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() Commented Sep 18, 2017 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) Commented Sep 18, 2017 at 13:40
  • 1
    @CodeGorilla char TIM[timsize] usually works on newer compilers: Declaring an array with a non-constant size variable Commented Sep 18, 2017 at 13:51
  • VLAs are not part of the C++ standard. They work here because of a compiler extension. Commented Sep 18, 2017 at 14:01

1 Answer 1

5

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);

answered Sep 18, 2017 at 13:21
6
  • 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. Commented Sep 18, 2017 at 13:25
  • @ATE-ENGE Added to the answer. Commented Sep 18, 2017 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 :) Commented Sep 18, 2017 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 :) Commented Sep 18, 2017 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. Commented Sep 18, 2017 at 13:40

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.