Лекция. Символьные строки и функции обработки строк.
Строка представляет собой последовательность из одного или более символов, последним из которых является нулевой символ таблицы ASCII '\0'. Это единственный вид строки, определенный в C.
Язык C поддерживает строковые константы, называемые строковыми литералами. Строковый литерал – это любая последовательность символов, заключенная в двойные кавычки ("…"). В конце литерала компилятор автоматически добавляет нулевой символ.
Не следует путать понятия строки и символа. Символьная константа заключается в одинарные кавычки, а строковая – в двойные.
Например, 'c' – символьная константа, а "c" – строковая константа.
Литерал можно задать с помощью директивы препроцессора define:
#define STR "…"
Строковая переменная может быть сформирована как одномерный массив типа char, либо с помощью указателя на переменную типа char. Количество символов в массиве (объем выделяемой памяти) должно быть не меньше, чем количество символов в строке плюс один символ для хранения символа нуль.
Строковые переменные описываются либо как массивы символов, либо как указатели на символ, например:
char stroka[81]; //строка длинной до 80 символов
char *str; //указатель на строку
В первом случае память для строки выделяется (имя массива является адресом его первого символа), во втором случае – нет (выделяется только для указателя). Если строка будет вводится с клавиатуры, то лучше описать переменную как массив символов, иначе предварительно придется выделять память для строки, например, с помощью функции malloc().
Например, char *S1, S[10]="Yes"; S1=S;
При этом создаются переменная-указатель S1 и массив символов S, под который выделяется поле длиной 10 символов, 4 из которых будут заполнены. Затем в переменную-указатель записывается адрес символьного массива (рис. 1).

Рис. 1. Строковая константа и указатель
Функции gets() и puts()
Для вводы и вывода строк символов служат функции gets(), puts(). Функция gets() вводит с клавиатуры строку, заменяя символ «перевод строки» на нуль-символ, и помещает ее по указанному адресу. Например:
gets (stroka); /* ввод строки в массив строка */
Функция puts() выводит указанную строку на экран. Например, оператор
puts(str);
выведет на экран строку, на которую указывает переменная str, курсор после вывода переместится на новую строку.
Функции обработки строк
Для работы со строками символов в библиотеке TurboС имеется ряд функций, например, функция определения длины строки strlen(), копирования строк strcpy(), сцепления строк strcat(), сравнения строк strcmpQ, нахождения в строке указанного символа strchr(). Прототипы таких функций находятся в файле string.h, краткий их перечень приведен в следующем разделе.
Примеры обращения к функциям обработки строк:
#include <stdio.h>
#include <conio.h>
#include <string.h>
main()
{char s1[81],s2[81],s3[81];
char *s;
gets(s1);
printf ("Dlina stroki = %d\n", strlen(s1));
gets(s2);
if ((s=strchr(s2,'a'))!=NULL) /* есть буква 'а' в строке s2 */
*s = 'b'; /* замена в строке s2 первой буквы ‘a’ на ‘b’ */
puts(s);
gets(s3);
if (strcmp(s1,s3)==0)
printf("Stroki rani\n");
}
Рассмотрим одну из библиотечных функций – функцию сцепления двух заданных строк strcat(). Определение функции:
char *strcat (char *s1, char *s2); Функция копирует строку s2 (на которую ссылается указатель s2) в конец строки s1 и возвращает значение s1 – ссылку на сцепленную строку.
Работу функции можно описать так:
char *strcat (char *s1, char *s2)
{char *rs; /* ссылка на результирующую строку */
rs=sl; /* запоминание адреса начала строки si*/
while (*sl!=’\0’)
s1++; /* поиск конца строки s1 */
/* копирование строки s2 в конец s1*/
while (*s2!=’\0’)
{ *s1=*s2;
s1++;
s2++;
}
*s1=’\0’;
return rs;
}
Как видите, функция не проверяет, достаточно ли памяти для результирующей строки. Вызывающая программа должна позаботиться об этом.
А теперь посмотрите на более компактную (но менее понятную) запись этой функции:
char *strcat (char *s1, char *s2)
{ char *rs;
rs=s1; /* запоминание адреса начала строки s1*/
while (*sl!=’\0’)
sl++; /* поиск конца строки s1*/
while ((*sl++ = *s2++)!='\0'); //копирование s2 в конец s1включая нуль-символ */
return rs;
}
Даже еще можно сократить текст функции, записав, второй оператор while короче:
while (*sl++ = *s2++);
Каждый раз очередной символ из второй строки копируется в первую, затем значения указателей s1 и s2 увеличиваются на 1, т.е. происходит продвижение указателей к следующим символам строк. Этот процесс повторяется до тех пор, пока не скопируется нуль-символ (т.к. выход из цикла происходит при нулевом значении выражения в скобках).
Полный текст программы выглядит следующим образом:
#include <stdio.h>
#include <string.h>
#include <conio.h>
char *strcat (char *s1, char *s2)
{char *rs; /* ссылка на результирующую строку */
rs=s1; /* запоминание адреса начала строки s1*/
while (*s1!='\0')
s1++; /* поиск конца строки s1 */
/* копирование строки s2 в конец s1*/
while (*s2!='\0')
{ *s1=*s2;
s1++;
s2++;
}
*s1='\0';
return rs;
}
main()
{char st1[80],st2[80],rs[160];
gets(st1);
gets(st2);
*strcat(st1,st2);
puts(st1);
getch();
}
Пример драйвера для функции сцепления строк strcatQ:
#include<stdio.h>
main()
{char strl[81],str2[81];
puts ("Введите две строки”);
gets(str1);
gets(str2);
if (strlen(strl)+strlen(str2) < 81)
{puts ("Результат:");
puts (strcat(strl,str2));
printf ("Строки после вызова функции сцепления: \n %s \n %s \n", strl, str2);
}
else puts ("Heхватает памяти для результирующей строки");
getch();
}
Пример
// Замена строчных букв на заданный символ
char *zamenaBukv(char *str, char sim)
{int i;
for(i=0;str[i]; i++) //str[i]!=’\0’
if (str[i]>=’a’&&str[i]<=’z’) str[i]=sim;
return str;
}
//второй вариант замены букв
char *zamenaBukv(char *str, char sim)
{char *s;
for(s=str; *s!=’\0’; s++)
if (*s>=’a’ && *s<=’z’) *s=sim;
return str;
}
//Вызов
char c, s[81];
gets(s);
c=’*’;
puts(zamenaBukv(s,c));






