Sscanf и конечные символы

Я пытаюсь использовать sscanf для простого теста и преобразования, но у меня возникает проблема с тем, что он игнорирует конечный мусор в строке. Мой пример кода:

char *arg = "some user input argument";
int val = 0;
if (sscanf(arg, "simple:%d", &val) == 1) {
 opt = SIMPLE;
} else if (strcmp(arg, "none") == 0) {
 opt = NONE;
} else {
 // ERROR!!!
}

Это отлично работает для ожидаемых входов, например:

arg = "simple:2" --> opt = SIMPLE val = 2
arg = "none" --> opt = NONE val = 0

Но моя проблема заключается в том, что конечные символы после "простого" значения молча игнорируются

ACTUAL : arg = "simple:2GARBAGE" --> opt = SIMPLE val = 2
DESIRED: arg = "simple:2GARBAGE" --> ERROR!!!

Какой простой способ получить sscanf для отчета о конечном мусоре? Или, поскольку я читал "scanf is evil", существует ли простая (возможно 1-линейная) альтернатива sscanf для решения вышеуказанной проблемы?

2 ответа

sscanf() для дополнительного char. Не удалось найти его.

char ch;
// If _nothing_ should follow the `int`
if (sscanf(arg, "simple:%d%c", &val, &ch) == 1) Success();
// or if trailing white-space is OK
if (sscanf(arg, "simple:%d %c", &val, &ch) == 1) Success();

В другом идиоматическом решении используется %n

int n;
// If _nothing_ should follow the `int`
if (sscanf(arg, "simple:%d%n", &val, &n) == 1 && arg[n] == '\0') Success();
// or if trailing white-space is OK
if (sscanf(arg, "simple:%d %n", &val, &n) == 1 && arg[n] == '\0') Success();


Вы можете использовать следующее:

char rest[64] = "";
[...]
if ( sscanf(arg, "simple:%d%s", &val, rest) == 1 ) {

и проверьте содержимое или длину rest.

Это работает, потому что %s, следующий за %d, будет содержать любые символы, следующие за допустимым числом. Вы можете отрегулировать размер rest по мере необходимости для ваших нужд.

См. здесь для рабочего примера.

licensed under cc by-sa 3.0 with attribution.