Вы можете уменьшить эту функцию до:
int cnt = sscanf(str, "%x", &val);
if (cnt == 1) {
// read a valid `0xNNNN` string
}
scanf
с форматом %x
уже выполняет шестнадцатеричное преобразование и отлично справляется с префиксом 0x
. Кроме того, его возвращаемое значение - это количество совпадающих элементов, так что вы можете использовать это, чтобы определить, действительно ли он нашел шестнадцатеричное значение в str
или нет.
При этом у вас есть обе части информации, которые вам нужны: была ли строка отформатирована так, как вы ожидали, и какое значение было (правильно преобразовано). Это также позволяет избежать выделения строк (которое вы не освобождаете) и ошибки, которую ваш код имеет, если strlen(str)
меньше двух.
Если вы измените свою подпись функции на:
int check_and_get_hex(const char *str, int *val);
(или что-то в этом роде), соответственно обновите вызов sscanf
(передавая val
вместо &val
) и вернув (cnt == 1)
, вы можете получить как «это правильная шестнадцатеричная строка», так и значение звонящему за один выстрел.