Based on accepted answer, I updated the snipped.
It support float input (like 1.5k
), support hexadecimal input (like 0x55k
), drop gotos
and use a string as list of units to avoid the switch and makes the update easy.
static char *human_readable_suffix = "kMGT";
size_t *parse_human_readable(char *input, size_t *target) {
char *endp = input;
char *match = NULL;
size_t shift = 0;
errno = 0;
long double value = strtold(input, &endp);
if(errno || endp == input || value < 0)
return NULL;
if(!(match = strchr(human_readable_suffix, *endp)))
return NULL;
if(*match)
shift = (match - human_readable_suffix + 1) * 10;
*target = value * (1LU << shift);
return target;
}
Here are the tests result:
1337 => 1337 [ok, expected: 1337]
857.54 => 857 [ok, expected: 857]
128k => 131072 [ok, expected: 131072]
1.5k => 1536 [ok, expected: 1536]
8M => 8388608 [ok, expected: 8388608]
0x55 => 85 [ok, expected: 85]
0x55k => 87040 [ok, expected: 87040]
1T => 1099511627776 [ok, expected: 1099511627776]
32. => 32 [ok, expected: 32]
-87 => error (expected)
abcd => error (expected)
32x => error (expected)
Full code can be found at: https://gist.github.com/maxux/786a9b8bf55fb0696f7e31b8fa3f6b9d