I am using the standard <regex.h>
library to match a complex string. Some matches are integers and my current solution is to use to_integer
:
int to_integer(regmatch_t match, const char* str) {
char buffer[16];
int end = match.rm_eo - match.rm_so;
memcpy(buffer, &str[match.rm_so], end);
buffer[end] = '\0';
return atoi(buffer);
}
struct data {
int foo, bar, baz;
};
struct data fetch(char *string) {
int groups = 4;
regmatch_t matches[groups];
if (regexec(®ex, string, groups, matches, 0)) abort();
return (struct data){
to_integer(matches[1], string),
to_integer(matches[2], string),
to_integer(matches[3], string)
};
}
Is there a more elegant way that does not involve an intermediate buffer?
Without an intermediate buffer, the following would eventually fail: ([0-9]{3})[0-9]{2}
. I also cannot modify str
in place because it is constant.
EDIT
From this question I wrote the following:
int to_integer(regmatch_t match, const char* str) {
const char *end = &str[match.rm_eo];
return strtol(&str[match.rm_so], (char**)&end , 10);
}
Unfortunately, the explicit cast (char*)
is quite ugly. My previous solution involving a copy of the string looks a bit safer IMHO.