Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Разложение строк на подстроки



Программы часто нуждаются в выделении подстрок из символьных буферов или других больших строк. Например, программа построения индекса базы данных должна знать местонахождение всех слов в текстовом файле. (Эти проблемы решаются с помощью методов обработки файлов, рассмотренных в главе 7.)

Прикладное программирование часто требует нахождения компонентов строки, или лексем: этот процесс называется синтаксическим анализом. Если составные части строки отделены друг от друга запятыми, пробе­лами или другими разделителями, вы можете использовать функцию strtok() для разложения строки на не­сколько подстрок.

Возможно, потребуются некоторые усилия, чтобы понять, как нужно использовать функцию strtok(), но время будет потрачено не зря - вы будете вознаграждены возможностью пользоваться этой мощной строко­вой функцией. Рассмотрим следующие объявления:

char s[] = "Now I know my ABCs";

char *p1, *p2, *p3. *p4, *p5;

Строка s является символьным массивом, инициализированным строкой из детской алфавитной песенки. Пять указателей на тип char пока что не инициализированы - скоро вы увидите, как функция strtok() ис­пользует эти указатели, чтобы сделать разбор строки, адресуемой указателем s. Сначала вызовите функцию strtok(), передав в качестве первого аргумента указатель на строку, а в качестве второго - разделительный символ (представленный в данном случае строкой, состоящей из одного символа пробела):

р1 = strtok(s," ");

Функция strtok() возвращает адрес первого компонента, отделенного от следующего заданным разделите­лем: в данном примере - пробелом. Разделитель должен представлять собой строку, состоящую из одного символа. Например, чтобы разложить строки на элементы, разделенные запятыми, используйте в качестве второго аргумента функции strtok() строку ",", а не символ ','. Рис. 6.5 иллюстрирует состояние перемен­ных программы как раз на этой стадии.

Как показано на рис. 10.6, функция strtok() вставляет нулевой байт (представленный на рисунке как /0) в позицию первого заданного ограничителя. Тем самым создается маленькая подстрока, адрес которой возвращается функцией strtok(), а в данном примере


присваивается переменной р1. Если задан­ные разделители не обнаружены, функция strtok() возвращает нуль. Кроме того, эта функция настраивает свой внутренний ука­затель на символ, следующий за концом по­следней сформированной подстроки, чтобы последующий вызов strtok() мог продол­жить разложение строки. Для этого передай­те в качестве первого аргумента макроопре­деление NULL - это послужит сигналом для функции strtok() использовать ее внут­ренний указатель как стартовый адрес для поиска другого разделителя. Таким образом, чтобы выделить другие компоненты строки, нужно просто вызвать функцию strtok() несколько раз, и каждый раз первым ее аргументом должен быть NULL:

р2 = strtok(NULL, " ");

рЗ = strtok(NULL, " ");

р4 = strtok(NULL, " ");

р5 = strtok(NULL, " ");

Рис. 6.5. После первого вызова функции strtok() для разложения строки на подстроки

На рис. 6.6 показана разобранная строка и ее указатели от р1 до р5. Каждый указатель адресует завер­шающуюся нулем подстроку внутри первоначальной строки. Каждая из подстрок теперь является отдельной строковой переменной, и эти пять указателей можно передавать другим строковым функциям, таким как strlen(), strcpy() и strdup().

Замечание

Функция strtok() непосредственно модифицирует исходную строку, поэтому перед ее разбором убедитесь, что вы сделали ее копию на случай необходимости ее использования в первоначальном виде.

В предыдущем примере предпо­лагалось, что можно было заранее узнать, сколько компонентов имеет строка. В большинстве же случаев это невозможно, и адресация компо­нентов строк с помощью индивиду­альных указателей на практике не применяется.

Чтобы выделить составляющие строки, более разумно было бы ис­пользовать цикл, в котором резуль­таты работы функции strtok() пере­давались бы другим строковым функциям. Такой цикл обычно выглядит следующим образом:

р = strtok(buffer, ";");

while (р) {

/* Обработка подстроки, адресуемой указателем р */

р = strtok(NULL, ";");

}

Рис. 6.6. После разбора строки с помощью функции strtok()

Сначала указатель р устанавливается равным результату функции strtok(), которой были переданы указа­тель на исходную строку buffer и разделитель ";". Затем цикл while проверяет значение указателя р на равен­ство нулю. Если указатель р имеет ненулевое значение, то он адресует очередную подстроку в строке buffer и вы можете передавать его другой строковой функции. После обработки найденной подстроки внутри цикла осуществляется попытка поиска других подстрок с помощью нового вызова функции strtok(), но теперь в качестве первого аргумента передается макроопределение NULL.

Листинг 6.10 показывает, как использовать функцию strtok() для выделения слов из строки. Скомпили­руйте и запустите программу. Затем (когда программа предложит сделать ввод) введите строку, состоящую из слов, разделенных пробелами. Операторы в строках 14-18 выполнят анализ сделанного вами ввода и отобра­зят его результаты в виде отдельных слов.

Листинг 6.10. TOKENS.С (анализ строки слов)

1: #include <stdio.h>

2 #include <string.h>

3:

4: main()

5: {

6: char buffer[128];

7: char *p;

8:

9: printf("Enter a string of words separated by blanks.\n");

10: printf(": ");

11: gets(buffer);

12: printf("As entered: %s\n", buffer);

13: printf("As words (tokens);\n");

14: p = strtok(buffer. " ");

15: while (p) {

16: puts(p);

17: p = strtok(NULL, " ");

18: }

19: return 0;

20: }

____________________________________________________





Дата публикования: 2015-01-23; Прочитано: 211 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.011 с)...