0

So I have a string like this:

char numbers[] = "123,125,10000000,22222222222]"

This is an example, there can be lots more of numbers in the array but it will certainly end with a ].

So now I need to convert it to an array of unsigned long longs. I know I could use strtoull() but it takes 3 arguments and I don't know how to use that second argument. Also I would like to know how I can make my array have the right length. I would like to have my code look like this, but not in pseudocode but in C:

char numbers[] // string of numbers seperated by , and at the end ]
unsigned long long arr[length] // get the correct length
for(int i = 0; i < length; i++){
    arr[i]=strtoull(numbers,???,10)// pass correct arguments
}

Is this possible in C to do it like that?

fangio
  • 1,746
  • 5
  • 28
  • 52
  • 2
    What about the documentation of that function is unclear? – too honest for this site Nov 22 '16 at 23:08
  • 1
    The use of the second argument, what is that, how to initialize, what does it do? – fangio Nov 22 '16 at 23:10
  • 1
    What did you find out yourself? Why did you not read the documentation? Did you even try to search for that function? We are no tutoring site, you are expected to have done at least some **minimal efort to solve your problem yourself**. I don'tr see that in your question. – too honest for this site Nov 22 '16 at 23:12
  • http://www.cplusplus.com/reference/cstdlib/strtoull/ is the documentation I read, the example looks like my problem, I should have added it to my question, because I could use it but did not understand the second argument – fangio Nov 22 '16 at 23:18
  • The descriptions looks very clear to me. I don't see how this can be much better explained. No offence, but could it be that you miss some commonly used terms in C programming? – too honest for this site Nov 22 '16 at 23:20
  • 1
    See [Correct usage of `strtol()`](http://stackoverflow.com/questions/14176123/) for the details about how to detect whether a string is converted properly with `strtol()`. Most of what it says applies to `strtoull()` too; the main differences are that you use different constants and don't have to check for negative overflow. – Jonathan Leffler Nov 22 '16 at 23:20

1 Answers1

2

The second argument to strtoull is a pointer to a char * that will receive a pointer to the first character after the number in the string argument. The third argument is the base to use for conversion. Base 0 allows for a 0x prefix to specify hexadecimal conversion and a 0 prefix to specify octal, just like the C integer literals.

You can parse your line this way:

extern char numbers[]; // string of numbers separated by , and at the end ]
unsigned long long arr[length] // get the correct length
char *p = numbers;
int i;
for (i = 0; i < length; i++) {
    char *endp;
    if (*p == ']') {
        /* end of the list */
        break;
    }
    errno = 0;  // clear errno
    arr[i] = strtoull(p, &endp, 10);
    if (endp == p) {
        /* number cannot be converted.
           return value was zero
           you might want to report this error
        */
        break;
    }
    if (errno != 0) {
        /* overflow detected during conversion.
           value was limited to ULLONG_MAX.
           you could report this as well.
         */
         break;
    }
    if (*p == ',') {
        /* skip the delimiter */
        p++;
    }
}
// i is the count of numbers that were successfully parsed,
//   which can be less than len
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • *The second argument to `strtoull` is a pointer to a pointer that will receive a pointer* -- `>_<` – Robert Harvey Nov 22 '16 at 23:20
  • so I should use a length for my array that is big enough and it will only be filled to i? – fangio Nov 22 '16 at 23:21
  • Note that the `strtoull(p, &p, base)` notation means you cannot detect after the call whether there was a successful conversion because you've overwritten the information needed to know. You've not set `errno` to zero before calling it, so you can't detect overflows reliably. – Jonathan Leffler Nov 22 '16 at 23:23
  • That's fine if you point it out — it works for the given string where nothing goes wrong, but there are many strings where it won't work very well, such as `"123,125,10000000,22222222222["`. At least it doesn't write out of bounds of the array; it just puts zeroes into all elements after the first 4 for this deviant string. – Jonathan Leffler Nov 22 '16 at 23:28
  • if the string is like in the example and the numbers are never bigger than unsigned long long MAX, this code works. – fangio Nov 22 '16 at 23:30
  • @fangio: If you're sure there'll never be a problem of any sort with the data, then yes, it works. You're a braver man than I am if you dare assume that the data will always be well-formed. – Jonathan Leffler Nov 22 '16 at 23:32
  • 1
    @JonathanLeffler: Only the brave make the necessary effort to try and handle all cases and possibilities for failure. It is a humbling exercise, as the devil lies in the detail and there is always one more bug. – chqrlie Nov 22 '16 at 23:38