Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | ||
|
Программы часто нуждаются в выделении подстрок из символьных буферов или других больших строк. Например, программа построения индекса базы данных должна знать местонахождение всех слов в текстовом файле. (Эти проблемы решаются с помощью методов обработки файлов, рассмотренных в главе 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 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!