Получить количество символов, прочитанных sscanf?

Я разбираю строку (a char*), и я использую sscanf для разбора чисел из строки в двойные символы, например:

// char* expression;
double value = 0;
sscanf(expression, "%lf", &value);

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

Очевидно, самым простым способом было бы как-то вычислить количество символов, которые sscanf анализирует, но если нет простого способа сделать это, я открыт для альтернативных вариантов двойного разбора. Однако в настоящее время я использую sscanf, потому что он быстрый, простой и читаемый. В любом случае, мне просто нужен способ оценить двойник и продолжить синтаксический анализ после него.

Ответ 1

Вы можете использовать спецификатор формата %n и предоставить дополнительный аргумент int * для sscanf():

int pos;
sscanf(expression, "%lf%n", &value, &pos);

Описание спецификатора формата n из стандарта C99:

Потребление не потребляется. Соответствующий аргумент должен быть указателем на целое число со знаком, в которое должно быть записано количество символов, считываемых из входного потока до сих пор этим вызовом функции fscanf. Выполнение директивы %n не увеличивает счетчик присваивания, возвращаемый при завершении выполнения функции fscanf. Аргумент не преобразуется, но один потребляется. Если спецификация преобразования включает символ подавления присваивания или ширину поля, поведение undefined.

Всегда проверяйте возвращаемое значение sscanf(), чтобы гарантировать, что выполнялись назначения, а последующий код не ошибочно обрабатывает переменные, значения которых не изменялись:

/* Number of assignments made is returned,
   which in this case must be 1. */
if (1 == sscanf(expression, "%lf%n", &value, &pos))
{
    /* Use 'value' and 'pos'. */
}

Ответ 2

int i, j, k;
char s[20];

if (sscanf(somevar, "%d %19s %d%n", &i, s, &j, &k) != 3)
    ...something went wrong...

Переменная k содержит счетчик символов до точки, в которой был сканирован конец целого числа, сохраненного в j.

Обратите внимание, что %n не учитывается в успешных конверсиях. Вы можете использовать %n несколько раз в строке формата, если вам нужно.