String to unsigned long long

I have a serial stream I am reading in and extracting a value out that represents time in millisecond precision.

I need this converted back to a long in order to use in other parts of the program such as adjust my RTC if needed. Here is an example of what I am doing:

//
// Illustration of a function to convert a String
// to a long int using the C library function atol()
// (Arduino version 19 and successors)
//
// </begin Editorial>
// Why (oh why) didn't they just put something like the following
// in WString.h?
//
//
//      const char * c_str() const {return _buffer;}
//
//
// Then the main program could have done something like the following
//
//    long x = strtol(str.c_str(), NULL, 10);
//
// </end Editorial>
//
//  davekw7x
//

void setup()
{
   Serial.begin(9600);
}

void loop()
{
   String str("1423168911386");
   Serial.print("The string   : ");
   Serial.println(str);
   
   long x = stringToLong(str);
   Serial.print("The long int : ");
   Serial.println(x);
   Serial.println();
   delay(1000);
}

//
// I would have preferred the argument to be (const String & s)
// but that would be inconsistent with the lame definition of
// toCharArray in WString.h
//
// It also would have required the prototype to be in a separate
// header, since the Arduino prototype collector doesn't
// work with arguments that are references.
//
// Oh, well...
//
//  davekw7x
//
unsigned long long stringToLong(String s)
{
   char arr[12];
   s.toCharArray(arr, sizeof(arr));
   return atoll(arr);
}

I am expecting the string “1423168911386” to come back in as a number. Currently, I am getting this output:

The string : 1423168911386
The long int : 1346787225

How do I convert this string into all of the digits I need?

Best Regards…

I am expecting the string “1423168911386” to come back in as a number

Punch into your calculator 232, and count the digits.

Where did these number come from? (Your number represents about 45 years of milliseconds)

Yes, the string in the example represents a date from a very long time ago. We could use this string as a more accurate representation of time.

"1423174622587"

I understand the 10 digit count.

Is there anything I can do in order to work with this as a number. I will eventually want to convert this back into seconds.

Thanks..

Presumably, it came from a 64 bit variable, so why not put it back into another? (Note: the Arduino supports 64 bit artithmetic, but it's slow and serial I/O isn't well supported.)

I can use an int64_t to hold my converted string but why does my output come out with a different number?

The string : 1423168911386 The long int : 1346787

I could understand if my result was 1423168911 but not 1349787

Regards.

A long integer variable cannot contain a 13 digit number. In the attempt to convert the string, overflow occurs, not truncation.

sfyffe:
How do I convert this string into all of the digits I need?

First of all you should avoid those ‘String’ objects that make your programs slow, RAM eating and incompatible to all the string functions in the AVR LIBC library!

Here is a solution for strings (char array, C-string, zero terminated string) instead of ‘String’ objects.

long long char2LL(char *str)
{
  long long result = 0; // Initialize result
  // Iterate through all characters of input string and update result
  for (int i = 0; str[i] != '\0'; ++i)
    result = result*10 + str[i] - '0';
  return result;
}

void LL2Serial(long long ll)
{
  uint64_t xx = ll/1000000000ULL;
  if (xx >0) Serial.print((long)xx);
  Serial.print((long)(ll-xx*1000000000));
}

void setup()
{
   Serial.begin(9600);
}

void loop()
{
   char str[]="1423168911386";
   Serial.print("The string   : ");
   Serial.println(str);
   
   long long x = char2LL(str);
  
   Serial.print("The long long: ");
   LL2Serial(x);   
   Serial.println();
   Serial.println();
   delay(1000);
}

There is one function that converts a char array to ‘long long’ and there is another function that prints a ‘long long’ on Serial.

YOU CANNOT print ‘long long’ directly to Serial, as Serial does not support the ‘long long’ data type. So I made a little helper function, inspired from a robtillaart posting found in this forum.

If you want to use slow and RAM-eating ‘String’ objects instead: Do the changes you need for yourself - I don’t want to support those freaking ‘String’ objects in any way.

P.S.: Which Arduino version supports a function “atoll(arr);”? Is that for Arduino DUE?

Jurs,

Not exactly sure what is on the DUO... This is for a custom board I created for the ESP8266 running an Atmel 644P..

Sometimes the string objest are just what we have to deal with especially using web services. Thanks for the code sample. I will work with it tomorrow and see what I can do.

Thanks,

Stephen

Sometimes the string objest are just what we have to deal with especially using web services.

No, you do not have to "deal with" String objects. There are much more sensible approaches.

sfyffe: Sometimes the string objest are just what we have to deal with especially using web services.

I think you mean, especially when we don't know how to write code. That's the only time you need String objects.

I don't have an Arduino here with me - does anyone know if "%lld" works in a sprintf?

@sfyffe: I deleted your foul-mouthed outburst and gave you a two day posting ban.

How do I convert this string into all of the digits I need?

Do you actually need all those digits ?

I can use an int64_t to hold my converted string but why does my output come out with a different number?

The string : 1423168911386 The long int : 1346787

Learn the difference between a 32 bit and a 64 bit int.

// Iterate through all characters of input string and update result
  for (int i = 0; str[i] != '\0'; ++i)
    result = result*10 + str[i] - '0';

It seems to me, you should not do this without checking that str is a valid numerical digit.