Использование strtok в c

Мне нужно использовать strtok для чтения в первом и последнем имени и отделить его. Как я могу сохранить имена, где я могу использовать их в двух отдельных массивах символов?

#include  #include  int main () { char str[] ="test string."; char * test; test = strtok (str," "); while (test != NULL) { printf ("%s\n",test); test= strtok (NULL, " "); } return 0; } 

Вот мой пример с достаточно простым помощником токенизации, который

  • сохраняет результаты в динамически растущем массиве
  • нулевое завершение массива
  • сохраняет строку ввода безопасной (strtok изменяет входную строку, которая является неопределенным поведением на литеральном char [], по крайней мере, я думаю, на C99)

Чтобы сделать повторный strtok_r в код, используйте нестандартный strtok_r

 #include  #include  #include  char** tokenize(const char* input) { char* str = strdup(input); int count = 0; int capacity = 10; char** result = malloc(capacity*sizeof(*result)); char* tok=strtok(str," "); while(1) { if (count >= capacity) result = realloc(result, (capacity*=2)*sizeof(*result)); result[count++] = tok? strdup(tok) : tok; if (!tok) break; tok=strtok(NULL," "); } free(str); return result; } int main () { char** tokens = tokenize("test string."); char** it; for(it=tokens; it && *it; ++it) { printf("%s\n", *it); free(*it); } free(tokens); return 0; } в #include  #include  #include  char** tokenize(const char* input) { char* str = strdup(input); int count = 0; int capacity = 10; char** result = malloc(capacity*sizeof(*result)); char* tok=strtok(str," "); while(1) { if (count >= capacity) result = realloc(result, (capacity*=2)*sizeof(*result)); result[count++] = tok? strdup(tok) : tok; if (!tok) break; tok=strtok(NULL," "); } free(str); return result; } int main () { char** tokens = tokenize("test string."); char** it; for(it=tokens; it && *it; ++it) { printf("%s\n", *it); free(*it); } free(tokens); return 0; } 

Ниже приведена strtok бесплатная повторная реализация (вместо этого используется strpbrk ):

 char** tokenize(const char* str) { int count = 0; int capacity = 10; char** result = malloc(capacity*sizeof(*result)); const char* e=str; if (e) do { const char* s=e; e=strpbrk(s," "); if (count >= capacity) result = realloc(result, (capacity*=2)*sizeof(*result)); result[count++] = e? strndup(s, es) : strdup(s); } while (e && *(++e)); if (count >= capacity) result = realloc(result, (capacity+=1)*sizeof(*result)); result[count++] = 0; return result; } 

Вам нужно хранить их отдельно? Два указателя в модифицированный массив символов будут иметь две отдельные идеально используемые строки.

То есть мы преобразуем это:

 char str[] ="test string."; 

В этом:

 char str[] ="test\0string."; ^ ^ | | char *s1 ----- | char *s2 ----------- 

,

 #include  #include  int main () { char str[] ="test string."; char *firstname = strtok(str, " "); char *lastname = strtok(NULL, " "); if (!lastname) lastname = ""; printf("%s, %s\n", lastname, firstname); return 0; } 

Как насчет использования strcpy :

 #include  #include  #include  #define MAX_NAMES 2 int main () { char str[] ="test string."; char *names[MAX_NAMES] = { 0 }; char *test; int i = 0; test = strtok (str," "); while (test != NULL && i < MAX_NAMES) { names[i] = malloc(strlen(test)+1); strcpy(names[i++], test); test = strtok (NULL, " "); } for(i=0; i 

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

 #include  #include  #include  char** split(const char *str, const char *delimiter, size_t *len){ char *text, *p, *first, **array; int c; char** ret; *len = 0; text=strdup(str); if(text==NULL) return NULL; for(c=0,p=text;NULL!=(p=strtok(p, delimiter));p=NULL, c++)//count item if(c==0) first=p; //first token top ret=(char**)malloc(sizeof(char*)*c+1);//+1 for NULL if(ret==NULL){ free(text); return NULL; } strcpy(text, str+(first-text));//skip until top token array=ret; for(p=text;NULL!=(p=strtok(p, delimiter));p=NULL){ *array++=p; } *array=NULL; *len=c; return ret; } void free4split(char** sa){ char **array=sa; if(sa!=NULL){ free(array[0]);//for text free(sa); //for array } } int main(void){ char str[] ="test string."; char **words; size_t len=0; int i; words = split(str, " \t\r\n,.", &len); /* for(char **wk = words; *wk ;wk++){ printf("%s\n", *wk); } */ for(i = 0;i 

Скопируйте результаты из strtok в новый буфер, используя функцию, такую ​​как

 /* * Returns a copy of s in freshly allocated memory. * Exits the process if memory allocation fails. */ char *xstrdup(char const *s) { char *p = malloc(strlen(s) + 1); if (p == NULL) { perror("memory allocation failed"); exit(1); } strcpy(p, s); return p; } 

Не забудьте free возвращаемые значения, когда вы закончите с ними.

IMO, вам не нужно (и, вероятно, не хочется) использовать strtok вообще (как в, «для этого, или многое из всего остального»). Я думаю, я бы использовал код примерно так:

 #include  #include  static char *make_str(char const *begin, char const *end) { size_t len = end-begin; char *ret = malloc(len+1); if (ret != NULL) { memcpy(ret, begin, len); ret[len]='\0'; } return ret; } size_t tokenize(char *tokens[], size_t max, char const *input, char const *delims) { int i; char const *start=input, *end=start; for (i=0; *start && i 

U тоже может сделать что-то подобное.

  int main () { char str[] ="test string."; char * temp1; char * temp2; temp1 = strtok (str," "); temp2 = strchr(str, ' '); if (temp2 != NULL) temp2++; printf ("Splitted string :%s, %s\n" , temp1 , temp2); return } 
Interesting Posts

CSS Обоснуйте текст, заполните пробел точками

Почему мы не можем использовать dispatch_sync в текущей очереди?

jQuery hasClass () – проверьте несколько classов

AngularJS изменяет URL-адрес на «небезопасно:» на странице расширения

Как добавить новую активность в существующий проект в Android Studio?

Почему администраторы не могут удалять ключи реестра при запуске regedit в качестве администраторов?

Как вы проверяете эффективность веб-сайта?

Как я могу сделать только одну страницу документа Word горизонтальной?

Как использовать разные разделители для команды sed substitute?

Как извлечь встроенные шрифты из PDF в качестве допустимых файлов шрифтов?

Airflow 1.9.0 – это очередность, но не запуск задач

Как изменить формат данных в формате long?

Фиксированная очередь размера, которая автоматически отбрасывает старые значения при появлении новых enques

Pandas groupby diff

С Unity, как я вставляю именованную зависимость в конструктор?

Давайте будем гением компьютера.