Получить количество символов, прочитанных 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
несколько раз в строке формата, если вам нужно.