C-определение используемого разделителя-strtok()
допустим, я использую strtok()
такой..
char *token = strtok(input, ";-/");
есть ли способ выяснить, какой токен фактически используется? Например, если входные данные были чем-то вроде:
Hello there; How are you? / I'm good - End
могу ли я выяснить, какой разделитель использовался для каждого токена? Мне нужно иметь возможность выводить определенное сообщение, в зависимости от разделителя, который следовал за токеном.
3 ответов
важно: strtok
не является повторным участником, вы должны использовать strtok_r
вместо него.
вы можете сделать это, сохранив копию исходной строки и посмотрев смещения текущего токена в эту копию:
char str[] = "Hello there; How are you? / I'm good - End";
char *copy = strdup(str);
char *delim = ";-/";
char *res = strtok( str, delim );
while (res) {
printf("%c\n", copy[res-str+strlen(res)]);
res = strtok( NULL, delim );
}
free(copy);
это выводит
;
/
-
EDIT: обработка нескольких разделители
Если вам нужно обрабатывать несколько разделителей, определяющих длина текущей последовательности разделителей становится немного сложнее: теперь вам нужно найти следующий токен, прежде чем решать, как долго будет последовательность разделителей. Математика не сложна, пока вы помните, что NULL
требует специального лечения:
char str[] = "(20*(5+(7*2)))+((2+8)*(3+6*9))";
char *copy = strdup(str);
char *delim = "*+()";
char *res = strtok( str, delim );
while (res) {
int from = res-str+strlen(res);
res = strtok( NULL, delim );
int to = res != NULL ? res-str : strlen(copy);
printf("%.*s\n", to-from, copy+from);
}
free(copy);
ты не можешь. strtok
перезаписывает следующий символ разделителя символом nul (чтобы завершить токен, который он возвращает на этот раз), и он не сохраняет Предыдущее значение, которое он перезаписывает. Первый раз, когда вы звоните strtok
в вашей строке примера,;
ушел навсегда.
вы можете что-то сделать, если вы держите немодифицированную копию строки, которую вы изменяете с помощью strtok
- учитывая индекс Терминатора nul для вашего текущего токена (относительно начало строки), вы можете посмотреть на тот же индекс в копии и посмотреть, что там было.
что может быть хуже, чем просто писать свой собственный код в отдельной строке, конечно. Вы можете использовать strpbrk
или strcspn
, если вы можете жить с результирующим токеном, не являющимся нулевым для вас.
человек 3 strtok
функции strtok() и strtok_r() возвращают указатель на начало каждого последующего токена в строке после замены сам токен с символом NUL. Когда нет остается больше токенов, возвращается нулевой указатель.
но с небольшой арифметикой указателей вы можете сделать что-то вроде:
char* string = "Hello,World!";
char* dup = strdup(string);
char* world = strtok(string, ",");
char delim_used = dup[world - string];
free(dup);