
Строки в С
.pdf
vk.com/club152685050
Строки в С
Строка - последовательность символов, заключенных в двойные кавычки.
В С, в отличие от многих других языков программирования, отсутствует специальный строковый тип.
Строка в С/С++ представляет собой массив элементов типа char, заканчивающийся нулевым символом (нуль-терминатор, нуль символ). Нулевой символ - это символ с кодом, равным 0, записывается в виде '\0'.
Таким образом, строка содержит символы, составляющие строку, а также нулевой символ.
Это единственный вид строки, определенный в С. char str[11]
Инициализация символьной строки при объявлении
Объявление массива str, предназначенного для хранения строки из 10 символов. Последний, 11-й байт предназначен для нулевого символа.
Строку при определении можно инициализировать: char st[10]="Hello";
с л о в о \0 \0 \0 \0 \0
Если строка при определении инициализируется, ее размерность можно опускать. Компилятор сам выделит соответствующее количество байт. Компилятор автоматически добавляет нулевой символ '\0' в конец строки. Большинство функций C++ используют
символ ‘\0’ для определения последнего символа строки. char str[]="Hello";
с л о в о \0
strlen(str)==5;
sizeof(str)==6
char str[]={'H', 'e', 'l' , 'l', 'o', '\0'};
Эти способы описания массива идентичны
К любому элементу строки, объявленному как массив символов, можно обратиться как к
элементу массива, по имени массива и индексу st[5]=' ';
st[6]='!'; st[7]='!'; st[8]='!';
st="bye-bye"; - ошибка
Имя массива st - это константный указатель на начало строчки "Hello". Значение константного указателя изменять нельзя.
Указатель на строковую константу (на массив символов). Строка в данном случае - это константный массив, размещенный в сегменте данных программы, изменять сегмент данных программы нельзя.
Данные, доступные при разыменовании указателя st1, доступны только для чтения char * st1="abcd"; //abcd\0
st1="def"; - можно, указатель ссылается на новую строку (указывает на 1й байт новой строки) st1[1]='W'; - ошибка, тк пытаемся изменить строковую константу
Пример.
char s1[]="12345"; char* s2="12345"; s1[0] = '!'; // ок!
s2[0] = '!'; // ошибка времени выполнения

vk.com/club152685050
Объяснение: Отличие в том, что s2 – это указатель на первый байт строки, которая размещена в сегменте данных программы, изменять который нельзя (строка – константа; s2 – указатель на константу, константу менять нельзя). s1 – это массив символов, память под строку будет выделена на стеке.
Различают несколько основных способов представления строк:
Pascal строки (первый символ – длина строки)
C строки (с маркером окончания)
Строки в виде классов
char s1[]="abc"; //инициализация, 0 автоматически добавляется в конец char s2[]={'a', 'b', 'c'};
char s3[]={'a', 'b', 'c', 0}; cout<<"sizeof(s1)="<<sizeof(s1)<<endl; // 4 cout<<"sizeof(s2)="<<sizeof(s2)<<endl; // 3 cout<<"sizeof(s3)="<<sizeof(s3)<<endl; // 4 char* s="abc";
s1="def"; // ошибка компилятора - cannot convert from 'const char [4]' to 'char [4]'
s1[1]='?';
s="12345";// работает, s - указатель на константную строку 12345 s[2]='a'; // ошибка; компилятор пропускает; ошибка времени выполнения -
т.к. пытаемся изменить константу
Ввод строки с клавиатуры и вывод на экран
Вариант 1) setlocale (LC_ALL, "rus"); char * st = new char[100]; cout<<"Введите имя и фамилию: "; cin>>st;
cout<<"Ваше имя: ";
setlocale (LC_ALL, "rus_rus.866"); cout<<st<<endl;
Введите имя: Иванов Петр
Ваше имя: Иванов
Вариант 2) #include <windows.h> SetConsoleCP(1251); SetConsoleOutputCP(1251); char * st = new char[100];
cout<<"Введите имя и фамилию: "; cin>>st;
cout<<"Ваше имя: "<<st<<endl;
Чтобы русские буквы отображались корректно, необходимо поменять тип шрифта консоли. Консоль -> свойства -> Шрифт -> выбрать Lucida Console, затем нажать ОК. считывает данные до ближайшего пробела
Функции чтения, определенные в классе iostream.
gcount() возвращает количество символов, считанных с помощью последней функции неформатированного ввода;
single character (1)
c-string (2)
stream buffer (3)
int get();
istream& get (char& c);
istream& get (char* s, streamsize n);
istream& get (char* s, streamsize n, char delim);
istream& get (streambuf& sb);
istream& get (streambuf& sb, char delim);
vk.com/club152685050
Чтение символа
get() извлекает символ из потока; возвращает код извлеченного из потока символа или EOF
get(c) возвращает ссылку на поток, из которого выполнялось чтение, и записывает извлеченный символ в с
Чтение строки
get(buf, num, lim='\n') считывает num-1 символов (или пока не встретится символ lim) и копирует их в символьную строку buf. Вместо символа lim в строку записывается признак конца строки ('\0'). Символ-разделитель lim остается в потоке, в buf не записывается. Возвращает ссылку на текущий поток;
getline(buf, num, lim='\n') считывает num-1 символов (или пока не встретится символ lim) и копирует их в символьную строку buf. Символ-разделитель извлекается из входного потока, уничтожается и в buf не записывается
buf - указатель на массив символов, где извлеченная строка хранится как С-строка num - максимальное количество считываемых символов. Если длина вводимой строки больше num-1, то возникает ошибка потока, состояние потока устанавливается в failbit lim - символ-разделитель; строка считывается из потока до тех пор пока не встретится символ lim
//char * st = new char[10]; char st[10];
cout<<"Введите имя и фамилию: "; cin.getline(st, 10); cout<<"Ваше имя: "<<st<<endl;
Введите имя и фамилию: Иванов Петр
Ваше имя: Иванов Пе (строка содержит 9 символов, + null десятый)
char st[20];//нужно минимум 12 символов, чтобы строчка поместилась
Пример. Программа при вводе строки большей длины должна выдавать сообщение об
ошибке и предлагать повторный ввод char st[10]; cout<<"Введите строку: "; cin.getline(st, 10);
while (cin.fail())
{cin.clear();
cin.sync(); // ф-я удаляет все непрочитанные символы из потока
cout<<"Длина строки должнв быть меньше 10! \n Введите строку повторно: "; cin.getline(st, 10);
}
cout<<st;
Пример. Посчитать кол-во букв И в строке и заменить их на "*". Определить длину строки int mylength=0, i=0; char s[100];
cout<<"Введите строку: "; cin.getline(s,100);
for (i=0; s[i];i++)
if ((s[i]=='И')||(s[i]=='и')) s[i]='*'; mylength=i;
cout<<s<<endl;
cout<<"Длина строки"<<mylength<<endl;
Пример выполнения программы:
Введите строку: Информатика и программирование *нформат*ка * программ*рован*е Длина строки 30
vk.com/club152685050
Как 'А' отличается от "А"
При рассмотрении программ на C++ вы можете встретить символы, заключённые в одинарные кавычки (например, 'А') и символы, заключённые в двойные кавычки ("А"). Символ внутри одинарных кавычек представляет собой символьную константу. Компилятор C++ выделяет только один байт памяти для хранения символьной константы. Однако символ в двойных кавычках представляет собой строковую константу - указанный символ и символ NULL (добавляемый компилятором). Таким образом, компилятор будет выделять два байта для символьной строки. Рисунок 17.3 иллюстрирует, как компилятор C++ хранит символьную константу 'А' и строковую константу "А".\
Рисунок. Как компилятор C++ хранит символьную константу 'А' и строковую константу "А".
Стандартные функции работы со строками и символами Функции стандартной библиотеки для работы с символами <ctype. h> и <cctype>)
Различают две группы функций: функции, выполняющие классификацию символов и функции, выполняющие преобразование символов
|
Функции проверки категории символа |
isalnum |
Проверяет, является ли аргумент буквой или цифрой |
isalpha |
Проверяет, является ли аргумент буквой |
iscntrl |
Проверяет, является ли аргумент управляющим символом |
isdigit |
Проверяет, является ли аргумент цифрой |
isgraph |
Проверяет, является ли аргумент символом, имеющим графическое представление |
islower |
Проверяет, является ли аргумент буквой в нижнем регистре |
isprint |
Проверяет, является ли аргумент символом, который может быть напечатан |
ispunct |
Проверяет, является ли аргумент символом, имеющим графическое представление, |
|
но не являющимся при этом буквой или цифрой |
isspace |
Проверяет, является ли аргумент разделительным символом |
isupper |
Проверяет, является ли аргумент буквой в верхнем регистре |
isxdigit |
Проверяет, является ли аргумент цифрой шестнадцатеричной системы счисления |
|
Функции изменения регистра |
tolower |
Изменить прописную букву на строчную («большую» на «маленькую») |
toupper |
Изменить строчную букву на прописную («маленькую» на «большую») |
int isalpha ( int c );
Функция возвращает 1, если символ является буквой, 0 а противном случае int tolower ( int c );
Если для символа параметра существует символ в нижнем регистре, функция возвращает код символа в нижнем регистре, в противном случае возвращает с (входной параметр.
Например, если параметр не буква или буква в нижнем регистре) cout<<'Z'<<tolower('Z')<<endl; // Z z
cout<<'?'<<tolower('?')<<endl; // ? ?
Для каждой из перечисленных функций есть ее аналог для многобайтных символов
типа wchar_t, содержащий в названии букву w: iswalpha, iswdigit ...
int iswalpha (wint_t c);
vk.com/club152685050
Функции для работы со строками «cstring» (string.h)
|
Копирование |
strcpy |
Копировать одну строку в другую |
strncpy |
Копировать заданное число символов одной строки в другую |
|
Объединение строк |
strcat |
Дописать одну строку к другой |
strncat |
Дописать заданное число символов из одной строки к другой |
|
Сравнение |
strcmp |
Сравнить две строки |
|
int strcmp ( const char * s1, const char * s2 ); |
|
Возвращаемое значение: |
|
<0 - если s1 меньше s2, |
|
0 - если s1=s2 |
|
>0 - если s1 больше s2 |
strncmp |
Сравнить заданное число первых символов двух строк |
|
|
|
Поиск вхождения символа |
strchr |
Найти первое вхождение символа в строку |
|
char * strchr (char * s, int ch); |
|
Функция возвращает указатель на первое вхождение символа ch в строку s, если его нет, то |
|
возвращается NULL. |
strcspn |
Найти первое вхождение символа из заданного множества в строку |
strpbrk |
Осуществить последовательный поиск всех вхождений символов заданного |
|
множества в строке |
strrchr |
Найти последнее вхождение символа в строку |
strspn |
Определить сколько символов заданного множества встречается с начала |
|
строки |
strstr |
Найти первое вхождение подстроки в строку |
strtok |
Разбить строку на части |
|
Другие |
strlen |
Вычислить длину строки |
Для ответа на вопрос билета необходимо привести пару примеров.