Простые операции со строками

Как выделить подстроку справа, например, имя файла? Просто найди символ, с которого начинается подстрока, и пользуйся указателем на него. На рисунке указатель filename показывает на строку «C:\WORK\FV.C», а указатель p — на часть этой строки «FV.C».

p = strrchr(filename, '\\') + 1; // Символ, следующий за последней обратной косой чертой

Как выделить подстроку слева, например, путь к файлу? Подставь нулевой байт в конец подстроки:

p = strrchr(filename, '\\');
*p = '\0'; // Теперь в filename записан путь к файлу

Чтобы вернуть имя файла, верни косую черту на прежнее место. Это гораздо быстрее, чем копировать путь в отдельную строку.

Как подсчитать, сколько раз символ встречается в строке? Можно каждый раз искать этот символ в оставшейся части строки и, если он был найден, увеличивать счетчик и сдвигаться к концу строки:

char *p = str; int n = 0;
while(p = strchr(p, 'А'))
p++, n++; // По окончании цикла n == число вхождений символа 'А' в строку str

В более удобочитаемом виде та же программа записывается следующим образом:

p = strchr(p, 'А');
while(p)
{ p++; // Продвигаемся к следующему за найденным символу
n++; // Засчитываем найденный символ
p = strchr(p, 'А');
}

Почему указатели быстрее, чем индексы массивов? Программеров, которые пришли из Паскаля или Бэйсика, может немного смутить код, приведенный выше. Для них привычнее обращаться к символу строки по индексу (его номеру в квадратных скобках):

for(i=0; i < strlen(s); ++i)
if(s[i] == 'A')
n++;

Чем лучше указатели? Да тем, что процессору не нужно при каждом проходе цикла складывать адрес начала строки s и переменную i, чтобы вычислить адрес s[i]:

xor ecx, ecx; ecx — это i
xor edx, edx; edx — это n
LOOP:
cmp DWORD PTR s[ecx], 'A'
jne SHORT BYPASS
inc edx
BYPASS:
inc ecx
cmp ecx, eax
jb SHORT LOOP

Вместо этого хорошая программа просто увеличивает адрес, то есть указатель p, а не индекс i. Код тела цикла становится немного проще и быстрее:

mov ecx, offset s; ecx — это p
xor edx, edx; edx — это n
LOOP:
cmp BYTE PTR [ecx], 'A'
jne SHORT BYPASS
inc edx
BYPASS:
inc ecx
cmp ecx, eax
jb SHORT LOOP

Здесь нужно сказать, что интеллектуальный компилятор может «додуматься» преобразовать код с индексом в код с указателем, но слишком надеяться на это не стоит. Компилятор все же не так умен, как использующий его программист:).

Как найти первую гласную или согласную букву в строке? Для этого случая лучше всего подходят функции strpbrk() и strspn().

p = strpbrk("стройка", "аеёиоуыэюя"); // p – указатель на первую гласную
p = s + strspn(s, "аеёиоуыэюя"); // p – указатель на первую согласную


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: