В программе строки могут определяться следующим образом:
Кроме того, должно быть предусмотрено выделение памяти для хранения строки.
Любая последовательность символов, заключенная в двойные кавычки «» , рассматривается как строковая константа .
Для корректного вывода любая строка должна заканчиваться нуль-символом "\0" , целочисленное значение которого равно 0. При объявлении строковой константы нуль-символ добавляется к ней автоматически. Так, последовательность символов, представляющая собой строковую константу, будет размещена в оперативной памяти компьютера, включая нулевой байт.
Под хранение строки выделяются последовательно идущие ячейки оперативной памяти. Таким образом, строка представляет собой массив символов. Для хранения кода каждого символа строки отводится 1 байт.
Для помещения в строковую константу некоторых служебных символов используются символьные комбинации. Так, если необходимо включить в строку символ двойной кавычки, ему должен предшествовать символ «обратный слеш»: ‘\»‘ .
Строковые константы размещаются в статической памяти. Начальный адрес последовательности символов в двойных кавычках трактуется как адрес строки. Строковые константы часто используются для осуществления диалога с пользователем в таких функциях, как printf() .
При определении массива символов
необходимо сообщить компилятору требуемый размер памяти.
char
m;
Компилятор также может самостоятельно определить размер массива символов, если инициализация массива задана при объявлении строковой константой:
char
m2=;
char
m3={"Т","и","х","и","е"," ","д","о","л","и","н","ы"," ","п","о","л","н","ы"," ","с","в","е","ж","е","й"," ","м","г","л","о","й","\0"
};
В этом случае имена m2 и m3 являются указателями на первые элементы массивов:
При объявлении массива символов и инициализации его строковой константой можно явно указать размер массива, но указанный размер массива должен быть больше, чем размер инициализирующей строковой константы:
char
m2="Горные вершины спят во тьме ночной."
;
Для задания строки можно использовать указатель на символьный тип
.
char
*m4;
В этом случае объявление массива переменной m4 может быть присвоен адрес массива:
m4 = m3;
*m4 эквивалентно m3="Т"
*(m4+1) эквивалентно m3="и"
Здесь m3 является константой-указателем. Нельзя изменить m3 , так как это означало бы изменение положения (адреса) массива в памяти, в отличие от m4 .
Для указателя можно использовать операцию увеличения (перемещения на следующий символ):
Иногда в программах возникает необходимость описание массива символьных строк
. В этом случае можно использовать индекс строки для доступа к нескольким разным строкам.
char
*poet = {"Погиб поэт!", "- невольник чести -"
,
"Пал," , "оклеветанный молвой…"
};
В этом случае poet
является массивом, состоящим из четырех указателей на символьные строки. Каждая строка символов представляет собой символьный массив, поэтому имеется четыре указателя на массивы. Указатель poet
ссылается на первую строку:
*poet
эквивалентно "П"
,
*poet[l]
эквивалентно "-"
.
Инициализация выполняется по правилам, определенным для массивов.
Тексты в кавычках эквивалентны инициализации каждой строки в массиве. Запятая разделяет соседние
последовательности.
Кроме того, можно явно задавать размер строк символов, используя описание, подобное такому:
char
poet;
Разница заключается в том, что такая форма задает «прямоугольный» массив, в котором все строки имеют одинаковую длину.
Описание
сhar *poet;
Большинство операций языка Си, имеющих дело со строками, работает с указателями. Для размещения в оперативной памяти строки символов необходимо:
Для выделения памяти под хранение строки могут использоваться функции динамического выделения памяти . При этом необходимо учитывать требуемый размер строки:
char
*name;
name = (char
*)malloc(10);
scanf("%9s"
, name);
Для ввода строки использована функция scanf()
, причем введенная строка не может превышать 9 символов. Последний символ будет содержать "\0"
.
Для ввода строки может использоваться функция scanf() . Однако функция scanf() предназначена скорее для получения слова, а не строки. Если применять формат "%s" для ввода, строка вводится до (но не включая) следующего пустого символа, которым может быть пробел, табуляция или перевод строки.
Для ввода строки, включая пробелы, используется функция
char
* gets(char
*);
char
* gets_s(char
*);
В качестве аргумента функции передается указатель на строку, в которую осуществляется ввод. Функция просит пользователя ввести строку, которую она помещает в массив, пока пользователь не нажмет Enter .
Для вывода строк можно воспользоваться рассмотренной ранее функцией
printf("%s"
, str); // str - указатель на строку
или в сокращенном формате
printf(str);
Для вывода строк также может использоваться функция
int
puts (char
*s);
которая печатает строку s и переводит курсор на новую строку (в отличие от printf() ). Функция puts() также может использоваться для вывода строковых констант, заключенных в кавычки.
Для ввода символов может использоваться функция
char
getchar();
Для вывода символов может использоваться функция
char
putchar(char
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include
#include
#include
int
main() {
char
s, sym;
int
count, i;
system("chcp 1251"
);
system("cls"
);
printf("Введите строку: "
);
gets_s(s);
printf("Введите символ: "
);
sym = getchar();
count = 0;
for
(i = 0; s[i] != "\0"
; i++)
{
if
(s[i] == sym)
count++;
}
printf("В строке\n"
);
puts(s); // Вывод строки
printf("символ "
);
putchar(sym); // Вывод символа
printf(" встречается %d раз"
, count);
getchar(); getchar();
return
0;
}
Результат выполнения
Основные функции стандартной библиотеки string.h приведены в таблице.
Функция | Описание |
char *strcat(char *s1, char *s2) |
присоединяет s2 к s1, возвращает s1 |
char *strncat(char *s1, char *s2, int n) |
присоединяет не более n символов s2 к s1, завершает строку символом "\0", возвращает s1 |
char *strсpy(char *s1, char *s2) |
копирует строку s2 в строку s1, включая "\0", возвращает s1 |
); strncpy(m3, m1, 6); // не добавляет "\0" в конце строки puts("Результат strncpy(m3, m1, 6)" ); puts(m3); strcpy(m3, m1); puts("Результат strcpy(m3, m1)" ); puts(m3); puts("Результат strcmp(m3, m1) равен" ); printf("%d" , strcmp(m3, m1)); strncat(m3, m2, 5); puts("Результат strncat(m3, m2, 5)" ); puts(m3); strcat(m3, m2); puts("Результат strcat(m3, m2)" ); puts(m3); puts("Количество символов в строке m1 равно strlen(m1) : " ); printf("%d\n" , strlen(m1)); _strnset(m3, "f" , 7); puts("Результат strnset(m3, "f" , 7)" ); puts(m3); _strset(m3, "k" ); puts("Результат strnset(m3, "k" )" ); puts(m3); getchar(); return 0; } Результат выполнения |
В современном стандарте C++ определен класс с функциями и свойствами (переменными) для организации работы со строками (в классическом языке C строк как таковых нет, есть лишь массивы символов char):
#include
#include#include
Для работы со строками также нужно подключить стандартный namespace:
Using namespace std;
В противном случае придётся везде указывать описатель класса std::string вместо string .
Ниже приводится пример программы, работающей со string (в старых си-совместимых компиляторах не работает!):
#include
Основные возможности, которыми обладает класс string:
Рассмотрим эти базовые возможности более подробно.
Инициализация строк при описании и длина строки (не включая завершающий нуль-терминатор):
String st("Моя строка\n"); cout << "Длина " << st << ": " << st.size() << " символов, включая символ новой строки\n";
Строка может быть задана и пустой:
String st2;
Для проверки того, пуста ли строка , можно сравнить ее длину с 0:
If (! st.size()) // пустая
или применить метод empty() , возвращающий true для пустой строки и false для непустой:
If (st.empty()) // пустая
Третья форма создания строки инициализирует объект типа string другим объектом того же типа:
String st3(st);
Строка st3 инициализируется строкой st . Как мы можем убедиться, что эти строки совпадают ? Воспользуемся оператором сравнения (==):
If (st == st3) // инициализация сработала
Как скопировать одну строку в другую ? С помощью обычной операции присваивания:
St2 = st3; // копируем st3 в st2
Для сцепления строк используется операция сложения (+) или операция сложения с присваиванием (+=). Пусть даны две строки:
String s1("hello, "); string s2("world\n");
Мы можем получить третью строку, состоящую из конкатенации первых двух, таким образом:
String s3 = s1 + s2;
Если же мы хотим добавить s2 в конец s1 , мы должны написать:
S1 += s2;
Операция сложения может сцеплять объекты класса string не только между собой, но и со строками встроенного типа. Можно переписать пример, приведенный выше, так, чтобы специальные символы и знаки препинания представлялись встроенным типом char * , а значимые слова – объектами класса string:
Const char *pc = ", "; string s1("hello"); string s2("world"); string s3 = s1 + pc + s2 + "\n"; cout << endl << s3;
Подобные выражения работают потому, что компилятор "знает", как автоматически преобразовывать объекты встроенного типа в объекты класса string . Возможно и простое присваивание встроенной строки объекту string:
String s1; const char *pc = "a character array"; s1 = pc; // правильно
Обратное преобразование при этом не работает . Попытка выполнить следующую инициализацию строки встроенного типа вызовет ошибку компиляции:
Char *str = s1; // ошибка компиляции
Чтобы осуществить такое преобразование, необходимо явно вызвать функцию-член с названием c_str() ("строка Си"):
Const char *str = s1.c_str();
Функция c_str() возвращает указатель на символьный массив, содержащий строку объекта string в том виде, в каком она находилась бы во встроенном строковом типе. Ключевое слово const здесь предотвращает "опасную" в современных визуальных средах возможность непосредственной модификации содержимого объекта через указатель.
К отдельным символам объекта типа string , как и встроенного типа, можно обращаться с помощью операции взятия индекса. Вот, например, фрагмент кода, заменяющего все точки символами подчеркивания:
String str("www.disney.com"); int size = str.size(); for (int i = 0; i < size; i++) if (str[i] == ".") str[ i ] = "_"; cout << str;
Replace(str.begin(), str.end(), ".", "_");
Правда, здесь использован не метод replace класса string , а одноимённый алгоритм:
#include
Поскольку объект string ведет себя как контейнер, к нему могут применяться и другие алгоритмы. Это позволяет решать задачи, не решаемые напрямую функциями класса string .
Ниже приводится краткое описание основных операторов и функций класса string , ссылки в таблице ведут к русскоязычным описаниям в интернете. Более полный список возможностей класса string можно получить, например, в Википедии или на сайте cplusplus.com .
Задание символов в строке |
|
operator= |
присваивает значения строке |
assign |
назначает символы строке |
Доступ к отдельным символам |
|
at |
получение указанного символа с проверкой выхода индекса за границы |
operator |
получение указанного символа |
front |
получение первого символа |
back |
получение последнего символа |
data |
возвращает указатель на первый символ строки |
c_str |
возвращает немодифицируемый массив символов С , содержащий символы строки |
Проверка на вместимость строки |
|
empty |
проверяет, является ли строка пустой |
size
|
возвращает количество символов в строке |
max_size |
возвращает максимальное количество символов |
reserve |
резервирует место под хранение |
Операции над строкой |
|
clear |
очищает содержимое строки |
insert |
вставка символов |
erase |
удаление символов |
push_back |
добавление символа в конец строки |
pop_back |
удаляет последний символ |
append |
|
operator+= |
добавляет символы в конец строки |
compare |
сравнивает две строки |
replace |
заменяет каждое вхождение указанного символа |
substr |
возвращает подстроку |
copy |
копирует символы |
resize |
изменяет количество хранимых символов |
Объявление строкСтрока в языке Си представляет собой одномерный массив символов, последним элементом которой является символ конца строки – нуль (строка, завершающаяся нулем, то есть NULL terminated string). Объявление переменной типа строка в языке Си возможно тремя способами, два из которых инициализируют строку во время объявления. Первый способ:Объявления массива символов (не забудьте добавить место для завершающего нуля): Char s; Второй способ:Присвоить строковой переменной начальное значение (при этом длину строки компилятор может вычислить сам): Char s = "Пример инициализации строки"; Справа от знака присваивания записана строковая константа. В конце строки автоматически добавляется ноль (‘\0’). Константы символьных строк помещаются в класс статической памяти. Третий способ:Неявное указание, что используется массив. В левой части от знака присваивания указывается указатель на символ: Char *s="Второй вариант инициализации"; Переменная s будет указателем на то место в оперативной памяти, где располагается строковая константа. В такой форме записи кроется потенциальная ошибка, заключающаяся в том, что указатель на символ часто называют строкой. Представленная ниже запись – это только указатель на символ, так как для размещения строки место не предусмотрено: Char *s; Ввод строки со стандартного устройства ввода (клавиатуры)Для работы со строками есть набор функций. Для ввода со стандартного устройства ввода (клавиатуры) чаще всего используются библиотечные функциями из модуля стандартного ввода-вывода: scanf и gets . Для ввода строки с помощью функции scanf , использует формат «%s » , причем обратите внимание на то, что перед идентификатором строки не используется знак адреса «& » , так как одномерный массив уже представлен указателем на его начало: Scanf("%s", s); Функция gets() считывает символы до тех пор, пока не достигнет символа перехода на новую строку. Функция принимает все символы вплоть до символа перевода строки, но не включает его. К концу строки добавляется завершающий ноль (‘\0’). Функция gets() помещает считанную с клавиатуры последовательность символов в параметр типа строка и возвращает указатель на эту строку (если операция завершилась успешно), или NULL (в случае ошибки). В приведенном ниже примере при успешном завершении операции, на экран будет выведено две одинаковые строки:
#include Попутно заметим, что функция gets часто используется для ввода лю-бых данных с клавиатуры в виде строки с целью дальнейшего преобразования функцией sscanf к нужному формату или для предварительного анализа вводимых данных, например:
#include Вывод строк на стандартное устройство вывода (экран монитора)Для вывода строк на стандартное устройство вывода (экран монитора) можно использовать две функции printf и puts . В функции printf в качестве формата передается «%s». Удобство использования этой функции заключается в том, что помимо строки можно сразу выводит данные других типов. Особенность функции puts заключается в том, что после вывода строки автоматически происходит переход на следующую строку. Функции для работы со строкамиДля преобразования строк в языке Си предусмотрена библиотека string. Каждая из функций имеет свой формат записи (прототип). Наиболее используемые функции рассмотрены в этой статье. — читать Пример программ(листинг) работающей со строками Программист говорит: Здравствуйте! Я прочел вашу статью. Мне было очень грустно и одновременно смешно. Особенно убивает эта ваша фраза: «Так как переменную типа char часто используют как массив, то определяют количество возможных значений». 😆 😆 😆 1. Значение переменной типа char присваивается так: Вот здесь: Char a = *"A"; Происходит разадресация указателя на массив и в результате возвращается значение первого элемента массива т.е. ‘A’ 2. Обнуление происходит так: Char a = NULL; //А так очищается строка в теле программы "" -- этот символ называется ноль-терминатор. Он ставится в конце строки. Вы сами того не зная заполнили этим символом массив s1 из вашей статьи. А ведь можно было присвоить этот символ только нулевому элементу массива. 3. Смело пользуитесь терминологией. Поймите меня правильно, статья в нынешнем виде не может существовать. Не поленитесь, перепишите ее. Удачи! Вы справитесь!
Здравствуйте еще раз!
|