Вложенная функция функции strtok в C
У меня есть строка вроде этого:
a;b;c;d;e f;g;h;i;j 1;2;3;4;5
и я хочу проанализировать элемент по элементу. Я использовал вложенную функцию strtok, но она просто разбивает первую строку и делает null указателем маркера. Как я могу это преодолеть? Вот код:
token = strtok(str, "\n"); while(token != NULL && *token != EOF) { char a[128], b[128]; strcpy(a,token); strcpy(b,a); printf("a:%s\n",a); char *token2 = strtok(a,";"); while(token2 != NULL) { printf("token2 %s\n",token2); token2 = strtok(NULL,";"); } strcpy(token,b); token = strtok(NULL, "\n"); if(token == NULL) { printf("its null"); } }
Вывод:
- Как читать ввод по-символам в Java?
- Ищете четкое определение того, что такое «токенизатор», «парсер» и «лексеры» и как они связаны друг с другом и используются?
- Шаблоны C ++ Угловые скобки Pitfall - Что такое C ++ 11?
- Как использовать stringstream для разделения разделенных запятыми строк
- Как лучше всего разбить строки csv в oracle 9i
token 2 a token 2 b token 2 c token 2 d token 2 e
- Есть ли функция для разделения строки в PL / SQL?
- Сканер против StringTokenizer против String.Split
- Разделение разделенной запятой строки в PL / SQL хранимой процедуре
- Токенизация строк в C
- Как сделать токенизацию строки в C ++?
- Как получить токен из Lucene TokenStream?
- Ошибка Tokenizing: java.util.regex.PatternSyntaxException, оборванный метасимвол '*'
- Тонирование и сортировка с помощью XSLT 1.0
Вы не можете сделать это с помощью strtok()
; используйте strtok_r()
из POSIX или strtok_s()
из Microsoft, если они доступны, или переосмыслите свой дизайн.
char *strtok_r(char *restrict s, const char *restrict sep, char **restrict lasts); char *strtok_s(char *strToken, const char *strDelimit, char **context);
Эти две функции взаимозаменяемы. Хотя strtok_s()
является необязательной частью C11 (Приложение K в ISO / IEC 9899: 2011), несколько поставщиков, кроме Microsoft, внедрили интерфейсы в этом разделе стандарта.
С strtok_r ()
#include #include int main(void) { char str[] = "a;b;c;d;e\nf;g;h;i;j\n1;2;3;4;5\n"; char *end_str; char *token = strtok_r(str, "\n", &end_str); while (token != NULL) { char *end_token; printf("a = %s\n", token); char *token2 = strtok_r(token, ";", &end_token); while (token2 != NULL) { printf("b = %s\n", token2); token2 = strtok_r(NULL, ";", &end_token); } token = strtok_r(NULL, "\n", &end_str); } return 0; }
Результаты
a = a;b;c;d;e b = a b = b b = c b = d b = e a = f;g;h;i;j b = f b = g b = h b = i b = j a = 1;2;3;4;5 b = 1 b = 2 b = 3 b = 4 b = 5
Без strtok_r ()
Это работает в контексте – при условии, что данные заканчиваются новой строкой.
#include #include int main(void) { char data[] = "a;b;c;d;e\nf;g;h;i;j\n1;2;3;4;5\n"; char *string = data; char *token = strchr(string, '\n'); while (token != NULL) { /* String to scan is in string..token */ *token++ = '\0'; printf("a = %s\n", string); char *token2 = strtok(string, ";"); while (token2 != NULL) { printf("b = %s\n", token2); token2 = strtok(NULL, ";"); } string = token; token = strchr(string, '\n'); } return 0; }
Вывод
a = a;b;c;d;e b = a b = b b = c b = d b = e a = f;g;h;i;j b = f b = g b = h b = i b = j a = 1;2;3;4;5 b = 1 b = 2 b = 3 b = 4 b = 5
strtok_r
– лучшее и безопасное решение, но есть также способ сделать это с помощью strtok
:
#include #include int main () { char str[] = "a;b;c;d;e\nf;g;h;i;j\n1;2;3;4;5\n"; char *line; char *token; char buf[256]; for (line = strtok (str, "\n"); line != NULL; line = strtok (line + strlen (line) + 1, "\n")) { strncpy (buf, line, sizeof (buf)); printf ("Line: %s\n", buf); for (token = strtok (buf, ";"); token != NULL; token = strtok (token + strlen (token) + 1, ";")) { printf ("\tToken: %s\n", token); } } return 0; }
Вывод:
Line: a;b;c;d;e Token: a Token: b Token: c Token: d Token: e Line: f;g;h;i;j Token: f Token: g Token: h Token: i Token: j Line: 1;2;3;4;5 Token: 1 Token: 2 Token: 3 Token: 4 Token: 5