При синтаксическом анализе строки, которая может содержать пустое поле между разделителями, strtok
нельзя использовать, поскольку strtok
будет рассматривать любое количество последовательных разделителей как один разделитель.
Так что в вашем случаеесли поля variable = values могут также содержать пустое поле между разделителями '&'
, необходимо использовать strsep
или другие функции, такие как strcspn
, strpbrk
или просто strchr
и пара указателей, которые помогут вам пройти вниз по строке.
Функция strsep
является функцией BSD и может не входить в вашу библиотеку C.GNU включает strsep
, и он предполагался как замена strtok
просто потому, что strtok
не может обрабатывать пустые поля.
(Если у вас нет strsep
, вам просто нужно сохранить указатель start и end и использовать функцию типа strchr
для поискакаждое вхождение '&'
устанавливает указатель end на единицу перед разделителем, а затем получает информацию var = value из символов между start и указатель конца , затем обновляя оба, чтобы указать один за разделителем и повторять.)
Здесь вы можете использовать strsep
с разделителем "&\n"
, чтобы найти каждый '&'
(* 1040)* char включен, предполагая, что строка была прочитана из файла с строковой функцией ввода, такой как fgets
или POSIX getline
).Затем вы можете просто позвонить strtok
, чтобы проанализировать текст var = value из каждого токена, возвращенного strsep
, используя "="
в качестве разделителя ('\n'
уже был удален из последнего токена, когдапарсинг с strsep
)
Пример вставки определенного пустого поля для обработки между "...gamename=1234&&square=1234..."
может быть следующим:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void) {
char array[] = "address=1234&port=1234&username=1234&password=1234"
"&gamename=1234&&square=1234&LOGIN=LOGIN",
*query = strdup (array), /* duplicate array, &array is not char** */
*tokens = query,
*p = query;
while ((p = strsep (&tokens, "&\n"))) {
char *var = strtok (p, "="),
*val = NULL;
if (var && (val = strtok (NULL, "=")))
printf ("%-8s %s\n", var, val);
else
fputs ("<empty field>\n", stderr);
}
free (query);
}
( примечание: strsep
принимает параметр char**
в качестве первого аргумента и изменяет аргумент так, чтобы он указывал на точку после разделителя, поэтому необходимо сохранить ссылку на начало исходной выделенной строки (query
выше)).
Пример использования / Вывод
$ ./bin/strsep_query
address 1234
port 1234
username 1234
password 1234
gamename 1234
<empty field>
square 1234
LOGIN LOGIN
( примечание: преобразование "1234"
в числовое значение оставлено вам)
Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.