The problem is that the call to strtok() in the original with "(" as delimiter skips over the opening (, but then doesn't find another to mark the end of the token, so the rest of the string is consumed. The second call to strtok() therefore has nothing to process and returns NULL.

The fixed code avoids that problem. The initial delimiter must include ( to skip that, and must include , to stop there. The second delimiter should include ); the other characters are not strictly needed.

Since you aren't inspecting the output pointer that's the second argument to strtoumax(), it may as well be NULL (aka 0) each time. Using strtoumax() and assigning the result to an int is a little odd. With the given data, it is OK, but more generally, it risks losing important information. The strtoX() functions are quite powerful but also remarkably delicate in how they report out of bounds values, etc. This usage throws away all that information (and you'd need to set errno to 0 before calling it, and you'd have to save the values in uintmax_t variables, to get and preserve the information accurately).

In this context, a more succinct (but not necessarily simpler) way to parse the input string would be:

Make sure you know why the spaces are present and why they are where they are. That may require careful scrutiny of the POSIX specification for sscanf(). You can decide to do without the spaces; you need to know what the consequences of doing so are. If you want to be sure that the whole string was parsed, use: