Лекции по проге / 11_Строки_Обработка
.pdf
Разбиение строки
При повторных вызовах функции strtok() в качестве первого параметра указывается NULL. В этом случае следующий разделитель заменяется нуль-символом и возвращается указатель на начало следующей подстроки
ВНИМАНИЕ! Результирующие строки находятся рядом друг с другом и имеют разную длину. Соблюдайте осторожность при их модификации: в случае превышения размера будет испорчена соседняя строка
|
исходная строка |
|
строка после |
21 |
повторного вызова |
|
A |
s |
t |
r |
i |
n |
g |
o |
f |
, |
, |
, |
t |
o |
k |
e |
n |
s \0 |
A \0 s |
t |
r |
i |
n |
g \0 o |
f |
, |
, |
, |
t |
o |
k |
e |
n |
s \0 |
||


token
Разбиение строки
char string[] |
= "A string of,,,tokens"; |
|
// исходная строка |
||||||||||||||||||||||||||
char seps[] |
|
= " ,"; |
|
|
// строка разделителей |
|
|
|
|||||||||||||||||||||
char *token; |
|
|
|
|
|
|
|
|
|
|
// ссылка на начало подстроки |
|
|
||||||||||||||||
token = strtok(string, seps); |
|
|
// выделение первой подстроки |
||||||||||||||||||||||||||
while(token != NULL) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
puts(token); |
|
|
|
|
|
|
|
|
|
|
// печать подстроки |
|
|
|
|||||||||||||||
token = strtok(NULL, seps); // выделение следующей подстроки |
|||||||||||||||||||||||||||||
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
исходная строка |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A |
|
|
s |
t |
r |
|
i |
n |
g |
|
o |
f |
, |
, |
, |
t |
o |
k |
e |
n |
s |
\0 |
||||||
строка после |
|
|
A |
\0 |
s |
t |
r |
|
i |
n |
g |
\0 |
o |
f |
\0 |
, |
, |
t |
o |
k |
e |
n |
s |
\0 |
|||||
разбиения |
token |
|
|
|
|
|
|
token |
|
|
|
|
|
|
token |
|
|
|
token |
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A |
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string |
|
|
|
|||||
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
of |
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tokens |
|
|
|
||||||
Задание
Указать, что будет напечатано на экране после выполнения следующего кода
23
Задание
// исходная строка
char string[] = "may, march, january";
char seps[]= " ,"; |
// строка разделителей |
char *words[20]; |
// ссылки на слова |
int i; |
// индекс слова |
int count; |
// кол-во слов в строке |
// Выделение слов в строке count = 0;
words[0] = strtok(string, seps); // выделение 1-го слова while(words[count] != NULL)
{
count++;
words[count] = strtok(NULL, seps); /* выделение след.
слова */
24 }
Задание
char tmp[21]; |
// буфер для обмена строк |
// Меняем первое и последнее слово местами if(count >= 2)
{
strcpy(tmp, words[0]); strcpy(words[0], words[count-1]); strcpy(words[count-1], tmp);
}
// Распечатываем слова for(i = 0; i < count; i++) { puts(words[i]); }
25
Некорректная работа со строками
После разбиения строки на слова получаем
string |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m |
a |
y |
\0 |
|
m |
a |
r |
c |
h |
\0 |
|
j |
a |
n |
u |
a |
r |
y |
\0 |
words
После обмена слов
string |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
j |
a |
n |
u |
a |
r |
y |
\0 |
c |
h |
\0 |
|
m |
a |
y |
\0 |
a |
r |
y |
\0 |
words
На экране печатается
|
january |
|
ry |
26 |
may |
|
Задание
Исправить программу так, чтобы массив words содержал слова в следующей последовательности
"january", march", "may"
27
Меняем не слова,а указатели на них
char *tmp; |
// буфер для обмена указателей |
// Меняем первое и последнее слово местами if(count >= 2)
{
tmp = words[0];
words[0] = words[count-1]; words[count-1] = tmp;
}
// Распечатываем слова for(i = 0; i < count; i++) { puts(words[i]); }
28
Корректная работа со строками
После разбиения строки на слова получаем
string |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m |
a |
y |
\0 |
|
m |
a |
r |
c |
h |
\0 |
|
j |
a |
n |
u |
a |
r |
y |
\0 |
words
После обмена значений указателей
string |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m |
a |
y |
\0 |
|
m |
a |
r |
c |
h |
\0 |
|
j |
a |
n |
u |
a |
r |
y |
\0 |
words
На экране печатается
|
january |
|
march |
29 |
may |
|
Это надо помнить!
Библиотечные функции корректно работают со строки только в том случае, если они заканчиваться нульсимволом
Если вы изменяете символы строки вручную (например через квадратные скобки) или применяете функции, не гарантирующие простановку нуль-сим- вола (например strncpy()), то необходимо самостоятельно следить за тем, чтобы строка заканчивалась
30 нуль-символом
