Есть несколько способов сделать это. string.h
предоставляет несколько функций, которые можно использовать: strtok()
, strsep()
, strchr()
или комбинацию strcspn()
и strspn()
в зависимости от ваших потребностей. Вы также можете всегда ходить по строке, выбирая нужные токены из строки и игнорируя пробелы и несколько включенных разделителей. На самом деле есть хорошая обучающая ценность указателя в подходе к этому пути с точки зрения образования.
Каждый раз, когда вы перебираете что-то, выбирая различные фрагменты, вместо того, чтобы пытаться включить несколько вложенных циклов while
, каждый из которых предназначен для Сканирование вперед, чтобы пропустить или найти определенный класс символов, часто более выгодно использовать state-l oop, где вы используете один или несколько флагов для отслеживания разных состояний. (строка для чтения символов в словах или между словами для чтения разделителей или пробелов и т. д. c ..). Таким образом, вложенные циклы не требуются, и вы просто используете по одному от l oop до l oop на каждый символ, отвечающий соответственно в зависимости от вашего текущего состояния.
Включение этого в работу для сканирования строки и выбора Выделите каждое из слов, оканчивающихся разделителем ';'
или пробелом, и сохраняя один флаг состояния int in;
, чтобы отслеживать, читаете ли вы символы в словах (in = 1;
) или между словами, обрабатывающими пробелы и разделители (* 1019). *) и использовать char *sp
в качестве указателя начала , указывающего на начало каждого слова, и userInput
в качестве указателя конца , указывающего на текущий читаемый символ, вы можете do:
void parse(char *userInput, char **splitInput, char delim, size_t nptrs)
{
int in = 0; /* simple in-word flag 0-false/1-true */
size_t n = 0; /* counter to protect splitInput bounds */
char *sp = userInput; /* start-pointer initialized to userInput */
while (n < nptrs - 1) { /* loop while pointers remain unfilled */
/* if at end, is whitespace or a delimiter */
if (!*userInput || isspace(*userInput) || *userInput == delim) {
if (in) { /* if in word */
splitInput[n++] = sp; /* set pointer to start-pointer */
splitInput[n] = NULL; /* set next pointer NULL */
}
in = 0; /* reset in flag zero */
if (*userInput) /* if space or delim, nul-terminate */
*userInput = 0;
else /* otherwise */
return; /* at end-of-string */
}
else { /* normal char */
if (!in) { /* if not in-word */
sp = userInput; /* set start-pointer to 1st good char */
in = 1; /* set in-word flag true */
}
}
userInput++; /* advance to next char */
}
}
( примечание: над символом delim
передается в качестве параметра вместе с nptrs
для передачи количества доступных указателей, чтобы вы могли защитить свои границы массивов указателей при заполнении указателей. Также обратите внимание, что функция всегда устанавливает следующий указатель в вашем массиве на NULL
в качестве часового, позволяя вам l oop над точкой inters в вашем массиве в main()
, пока не будет достигнуто NULL
, так как вы не возвращаете количество используемых указателей, либо как возвращаемую функцию, либо через параметр указателя)
Простой пример, который анализирует слова из " my; ; ; dog ;;; has;fleas ;"
с использованием ';'
или пробелами в качестве разделителей могут быть:
#include <stdio.h>
#include <ctype.h>
#define NPTR 32 /* if you need a constant, #define one (or more) */
void parse(char *userInput, char **splitInput, char delim, size_t nptrs)
{
int in = 0; /* simple in-word flag 0-false/1-true */
size_t n = 0; /* counter to protect splitInput bounds */
char *sp = userInput; /* start-pointer initialized to userInput */
while (n < nptrs - 1) { /* loop while pointers remain unfilled */
/* if at end, is whitespace or a delimiter */
if (!*userInput || isspace(*userInput) || *userInput == delim) {
if (in) { /* if in word */
splitInput[n++] = sp; /* set pointer to start-pointer */
splitInput[n] = NULL; /* set next pointer NULL */
}
in = 0; /* reset in flag zero */
if (*userInput) /* if space or delim, nul-terminate */
*userInput = 0;
else /* otherwise */
return; /* at end-of-string */
}
else { /* normal char */
if (!in) { /* if not in-word */
sp = userInput; /* set start-pointer to 1st good char */
in = 1; /* set in-word flag true */
}
}
userInput++; /* advance to next char */
}
}
int main (void) {
char s[] = " my; ; ; dog ;;; has;fleas ;", *split[NPTR] = { NULL }, **p = split;
parse (s, split, ';', NPTR);
while (*p)
printf ("'%s'\n", *p++);
}
( примечание: заголовок ctype.h
включен для использования функции isspace()
для проверять пробелы, а не связывать вместе операторы if()
, проверяя space
, '\t'
или '\n'
напрямую. Как правило, это хорошая практика.)
Пример использования / Вывод
$ ./bin/split_ptr_arr3
'my'
'dog'
'has'
'fleas'
Примечание: в выводе выше все включенные пробелы удалены.
Взгляд все закончилось и дайте мне знать, если у вас есть вопросы Существует буквально десятки способов подойти к разбиению строк, это всего лишь один общий и базовый c подход.