Вот очень простой пример, разбивающий вашу строку на части, сохраненные в массиве массивов символов, используя указатель начала и конца. В MAXL
и MAXW
определяет просто удобный способ, чтобы определить константы, которые используются для ограничения индивидуальной длины слова до 32 (31 символов + нуль-терминатор) и максимум 3 слов (частей) исходной строки:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXL 32
#define MAXW 3
int main (void) {
char string1[] = "hello\tfriend\n";
char *sp = string1; /* start pointer */
char *ep = string1; /* end pointer */
unsigned c = 0; /* temp character */
unsigned idx = 0; /* index for part */
char strings[MAXW][MAXL] = {{0}}; /* array to hold parts */
while (*ep) /* for each char in string1 */
{
if (*ep == '\t' || *ep == '\n') /* test if \t or \n */
{
c = *ep; /* save character */
*ep = 0; /* replace with null-termator */
strcpy (strings[idx], sp); /* copy part to strings array */
*ep = c; /* replace w/original character */
idx++; /* increment index */
sp = ep + 1; /* set start pointer */
}
ep++; /* advance to next char */
}
printf ("\nOriginal string1 : %s\n", string1);
unsigned i = 0;
for (i = 0; i < idx; i++)
printf (" strings[%u] : %s\n", i, strings[i]);
return 0;
}
Выход
$ ./bin/split_hello
Original string1 : hello friend
strings[0] : hello
strings[1] : friend
Использование strtok
просто заменяет ручной указатель логики с вызовом функции, чтобы разделить строку.
Обновлено завершений строк Обработка Пример
Как вы нашли, когда шаговый хотя строка, которую вы можете создать простой пример, как вам нужно, чтобы соответствовать текущей строке, но с немного больше вы можете расширить свой код, чтобы справиться с более широким спектром ситуаций. В вашем комментарии вы отметили, что приведенный выше код не обрабатывает ситуацию, когда в конце строки нет newline
. Вместо того, чтобы менять код, чтобы справиться с этой ситуацией, с небольшим размышлением вы можете улучшить код, чтобы он обрабатывал обе ситуации. Один из возможных подходов:
while (*ep) /* for each char in string1 */
{
if (*ep == '\t' || *ep == '\n') /* test if \t or \n */
{
c = *ep; /* save character */
*ep = 0; /* replace with null-termator */
strcpy (strings[idx], sp); /* copy part to strings array */
*ep = c; /* replace w/original character */
idx++; /* increment index */
sp = ep + 1; /* set start pointer */
}
else if (!*(ep + 1)) { /* check if next is ending */
strcpy (strings[idx], sp); /* handle no ending '\n' */
idx++;
}
ep++; /* advance to next char */
}
Перерыв на любой Формат/непечатных символов
Продолжая расширять символы, которые могут быть использованы для разделения строк, а не использовать дискретные значения для идентификации какие символы делят слова, вы можете использовать диапазон значений ASCII для идентификации всех непечатаемых или форматированных символов в качестве разделителей. Несколько иной подход может быть использован:
char string1[] = "\n\nhello\t\tmy\tfriend\tagain\n\n";
char *p = string1; /* pointer to char */
unsigned idx = 0; /* index for part */
unsigned i = 0; /* generic counter */
char strings[MAXW][MAXL] = {{0}}; /* array to hold parts */
while (*p) /* for each char in string1 */
{
if (idx == MAXW) { /* test MAXW not exceeded */
fprintf (stderr, "error: MAXW (%d) words in string exceeded.\n", MAXW);
break;
}
/* skip each non-print/format char */
while (*p && (*p < ' ' || *p > '~'))
p++;
if (!*p) break; /* if end of s, break */
while (*p >= ' ' && *p <= '~') /* for each printable char */
{
strings[idx][i] = *p++; /* copy to strings array */
i++; /* advance to next position */
}
strings[idx][i] = 0; /* null-terminate strings */
idx++; /* next index in strings */
i = 0; /* start at beginning char */
}
Это будет обрабатывать тестовую строку независимо от линии прекращения и независимо от количества вкладок или переводов строк включены. Взгляните на ASCII Table and Description в качестве ссылки на используемые диапазоны символов.
Возможный дубликат [Сплит-строка с разделителями в C] (http://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c) –
Существует 2 основных способа: (1) с 'strtok' или (2) использование простого указателя для определения начала каждого слова и символа разделителя, следующего за словом. –