Для студентов НИУ «МЭИ» по предмету Программирование и алгоритмизацияТест 2 верен на 95%Тест 2 верен на 95%
3,50521
2020-03-232020-03-23СтудИзба
Описание
Верно ли утверждение: Ключевое слово struct обязательно при объявлении типа «структура»?
да
нет
Объем памяти, занимаемый структурой, равен:
максимальному объему памяти составляющих полей
сумме объемов памяти полей (если исключить из рассмотрения особенности, связанные с выравниванием адресов памяти)
1 килобайту
Отметьте утверждения, несправедливые для объединения:
объем памяти, занимаемый объединением, равен максимальному объему памяти составляющих полей
поля объединения помещаются в одно и то же место памяти
компоненты объединения обязательно имеют одинаковый тип
Какие термины обозначают сложную структуру данных?
Структура
Массив
Таблица
Константа
Структуры в программировании нужны для …
объединения компонентов разного типа в одну переменную в соответствии с логикой задачи
уменьшения длины программы
Верно ли утверждение: «ключевое слово typedef обязательно при объявлении типа «структура»?
да
нет
Отметьте свойства, неправильные для структур:
компоненты структуры могут иметь одинаковый тип
в любой программе должны быть структуры
компоненты структуры могут иметь разный тип
все компоненты структуры имеют один и тот же тип
компонентой структуры может быть массив
компоненты структуры хранятся в последовательных ячейках оперативной памяти
число компонентов структуры может быть бесконечно
структуры нельзя использовать в подпрограмме
к компоненте структуры следует обращаться, используя ее имя
компонентой структуры может быть структура
Отметьте свойства, характерные для массивов
элемент массива может иметь один номер, а может иметь и несколько номеров
элементы массива хранятся в последовательных ячейках оперативной памяти
массивы необходимы для организации циклов
все элементы массива имеют один и тот же тип
все элементы массива имеют одинаковое имя и различаются номерами
массив состоит из конечного числа элементов
подпрограммы без массивов невозможны
число элементов массива может быть бесконечно
в любой программе должны быть массивы
Отметьте операции, являющиеся операциями выбора компоненты структурированной переменной:
>>
<-
. (точка)
->
Допустима ли инструкция: char *s=»text»?
да
нет
Имеется фрагмент кода:
void main()
{char a[10]=»слово»;
Какое значение имеет элемент массива a[5]?
0
русская буква «о»
неопределенное
В языке Си константа ‘a’ занимает … байтов памяти.
2
1
256
Строковый литерал «text» занимает … байтов памяти.
4
2
256
5
Какое значение вернет функция strcmp(s1, s2), если s1 и s2 объявлены так: char *s1=»abba», char *s2=»aaaa»;
отрицательное значение
положительное значение
0
Какое значение вернет функция strcmp(s1, s2), если s1 и s2 объявлены так:
char *s1=»8″, char *s2=»1000″;
положительное значение
отрицательное значение
0
Допустима ли инструкция: s=»text», если s описано так: char s[6]?
нет
да
Сколько байтов памяти занимает переменная str, объявленная с помощью инструкции: char str[]=»слово»?
6
5
0
256
Строковый литерал «1234567890» занимает … байтов памяти.
256
10
9
11
Имеется фрагмент кода:
void main()
{char a[10]=»слово»;
Какое значение имеет элемент массива a[6]?
неопределенное
русская буква «о»
пробел
0
В языке Си константа «a» занимает … байтов памяти.
2
1
256
3
Какое значение вернет функция strcmp(s1, s2), если s1 и s2 объявлены так: char *s1=»5″, char *s2=»100″;
отрицательное значение
0
положительное значение
Характеристики ответов (шпаргалок)
Список файлов
-
Тест 2 верен на 95%.docx 13,36 Kb
-
Тест 2 верен на 95%.txt 5,94 Kb
Хочешь зарабатывать на СтудИзбе больше 10к рублей в месяц? Научу бесплатно!
Начать зарабатывать
Комментарии
Сопутствующие материалы
Ответы на популярные вопросы
То есть уже всё готово?
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
А я могу что-то выложить?
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
А если в купленном файле ошибка?
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Нашёл ошибку?
Или хочешь предложить что-то улучшить на этой странице? Напиши об этом и получи бонус!
Бонус рассчитывается индивидуально в каждом случае и может быть в виде баллов или бесплатной услуги от студизбы.
Предложить исправление
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
516
Средний доход
с одного платного файла
Обучение Подробнее
|
Snaiffer 2 / 2 / 0 Регистрация: 13.03.2011 Сообщений: 18 |
||||||||||||
|
1 |
||||||||||||
|
09.10.2012, 13:54. Показов 20898. Ответов 15 Метки нет (Все метки)
Объясните, пожалуйста, что происходит при
Т.е. тут явно у нас присутствует только объявления указателя str, но как выделяется память для строки «hello»? И второй вопрос:
0 |
|
Заблокирован |
||||
|
09.10.2012, 14:09 |
2 |
|||
|
const char *str = «hello» — (конечно если есть ; вконце этой строки) — это объявление строкового литерала и такая запись равносильна такой
В результате такого объявления компилятор выделяет память под число символов в кавычках и к этому блоку автоматически пристыковывает \0 (т.е обнулять конец не следует)
char *str = «hello» ругается потому как строковые литералы подразумевают константность но поверь и такой код отработает(правда он не кашерен с точки зрения компиляторов строго работающих в стандарте)
0 |
|
5055 / 3115 / 271 Регистрация: 11.11.2009 Сообщений: 7,044 |
|
|
09.10.2012, 20:33 |
3 |
|
он не кашерен с точки зрения компиляторов строго работающих в стандарте Я бы сказал, что он не кошерен с точки зрения программиста, который забьёт на это предупреждение, а потом попробует изменить получившуюся «неконстантную строку». Поэтому советовал бы обращать внимание на сообщения компилятора.
это объявление строкового литерала и такая запись равносильна такой Не согласен с этим. В первом случае строка будет расположена в read-only памяти, и в момент присваивания указатель сохранит только адрес этих данных. Во втором же случае строку будет скопирована в массив (да, имеет место массив, а не указатель), сама строка скорее всего даже не сохранится в read-only памяти. Попытка изменить строку в первом случае (посредством снятия константности, например), скорее всего, приведёт к попытке программы, во втором же случае не должна вызвать проблем.
0 |
|
Заблокирован |
|
|
09.10.2012, 20:49 |
4 |
|
Во втором же случае строку будет скопирована в массив (да, имеет место массив, а не указатель), сама строка скорее всего даже не сохранится в read-only памяти. — любой массив это совокупность ячеек области памяти другое дело что да конст компилятор может запихнуть в страницы со служебной адресацией, а не конст зашить в общедоступную память, но в любом случае есть массив и указателем на него является str. Так что возможно различие в адресации, а так одно и тоже (теже яйца но с боку)
0 |
|
5055 / 3115 / 271 Регистрация: 11.11.2009 Сообщений: 7,044 |
|
|
09.10.2012, 20:53 |
5 |
|
-=ЮрА=-, согласен, с точки зрения программиста, которому надо просто где-то сохранить строку, известную на стадии компиляции, разницы никакой. Но о подобных различиях стоит знать хотя бы потому, что константная строка будет загружена вместе с приложением (поскольку хранится в исполняемом файле), а для заполнения массива вызываются подряд несколько (и довольно много для большой по объёму строки) операций записи в память. Это надо иметь ввиду.
0 |
|
Заблокирован |
|
|
09.10.2012, 21:02 |
6 |
|
С другой стороны, вряд ли кто-то будет «Войну и мир» таскать в исходнике и сохранять в массив, так что это совершенно не критично. — именно.
0 |
|
5055 / 3115 / 271 Регистрация: 11.11.2009 Сообщений: 7,044 |
|
|
09.10.2012, 21:11 |
7 |
|
-=ЮрА=-, да это-то понятно, «Война и мир» давно является собирательным названием, я его для пущего эффекта применил))
0 |
|
21275 / 8292 / 637 Регистрация: 30.03.2009 Сообщений: 22,656 Записей в блоге: 30 |
|
|
09.10.2012, 21:13 |
8 |
|
Объясните, пожалуйста, что происходит при https://www.cyberforum.ru/blogs/18334/blog97.html далее раздел 4
Почему компилятор выводит предупреждение, если написать предыдущую строчку без const? Там же, раздел 5.2
это объявление строкового литерала и такая запись равносильна такой Бред сивой кобылы. Можешь на это не отвечать, т.к. спорить с тобой всё равно не буду
1 |
|
panicwassano |
|
09.10.2012, 21:14
|
|
Не по теме: народ ну вы в личку рамситесь
0 |
|
|
|
09.10.2012, 21:16
|
|
Не по теме:
-=ЮрА=-, да это-то понятно, «Война и мир» давно является собирательным названием, я его для пущего эффекта применил)) да, я понял это, я умею смеяться;)
0 |
|
rangerx 2021 / 1620 / 489 Регистрация: 31.05.2009 Сообщений: 3,005 |
||||
|
09.10.2012, 22:02 |
11 |
|||
|
это объявление строкового литерала и такая запись равносильна такой А эти записи тоже равносильны?
0 |
|
1181 / 894 / 94 Регистрация: 03.08.2011 Сообщений: 2,461 |
|
|
09.10.2012, 22:18 |
12 |
|
Имя массива в любом случае константный указатель, в то время как указатель на константные данные можно изменить, что бы он указывал на другую область памяти.
0 |
|
2 / 2 / 0 Регистрация: 13.03.2011 Сообщений: 18 |
|
|
12.10.2012, 10:27 [ТС] |
13 |
|
Благодарю всех за разъяснение данного вопроса.
0 |
|
Заблокирован |
||||||||
|
12.10.2012, 12:04 |
14 |
|||||||
|
rangerx, вот такие записи идентичны,
речь шла именно об этом
http://codepad.org/TDMqKPXw Output: Добавлено через 5 минут Не по теме: rangerx, жду разъяснений раз уж начали детальный разбор…
0 |
|
ForEveR В астрале 8049 / 4806 / 655 Регистрация: 24.06.2010 Сообщений: 10,562 |
||||
|
12.10.2012, 12:20 |
15 |
|||
|
-=ЮрА=-, Неверно. Они не могут быть идентичны, потому что первое — просто присваивание адреса строкового литерала, а второе — создание массива и копирование символов из строкового литерала в него. http://liveworkspace.org/code/… 86a7b1cd4f
Какой код корректный, если перефразировать rangerx. Или оба корректны?
0 |
|
silent_1991 |
|||||
|
12.10.2012, 12:53
|
|||||
0 |
1.
char s[] = "text";
Объявление массива s типа char [] и инициализация этого массива строковым литералом "text". Т. е. s — это просто массив из пяти символов: t, e, x, t, \0.
Вы можете менять его:
s[0] = 'n'; /* s: "next" */
Но не можете переприсвоить сам массив s (это же массив):
char s[] = "text"; /* OK */
s = "another text"; /* Это ошибка. */
2.
char *s = "text"; /* до C++11 */
const char *s = "text"; /* начиная C++11 */
Объявление указателя s типа char * и присваивание ему указателя на первый элемент строкового литерала "text". Попытка изменить этот строковой литерал (s[0] = 'a', например), — это неопределенное поведение.
Однако сам указатель переприсваивать можно:
const char *p = "text"; /* OK */
p = "another text"; /* OK */
Начиная с C++11 строковые литералы могут быть прямо присвоены только const char * (т. е. только указателям на константный char).
3.
std::string s = "text";
Создание объекта s класса std::string и присваивание ему const char *1. Т. е. s — это не массив и не указатель, а объект.
Класс строк в свою очередь содержит множество различных возможностей: копирование, сравнение, конкатенация, изменение, поиск подстрок и так далее. Чего строки в стиле C (массивы), конечно лишены (если не принимать во внимание <cstring>).
Что лучше использовать?
Использовать нужно то, что больше подходит для конкретной задачи. У каждой обговоренной выше «строки» есть свои области применения.
- Выполняется неявное приведение типов: присваивается не
const char [N], что является типов для всех строковых литералов, а именно указатель. Также см. оператор присваивания класса строк.
Обработка строк
В языке C++ существуют два вида строковых переменных. Начнем с того, который достался языку C++ в наследство
от C. Этот способ работы со строками гораздо быстрее, но значительно менее удобен.
Объявление переменной
В языке C строка — это просто указатель на первый символ этой строки. Для того, чтобы данную строку можно
было обрабатывать при помощи библиотечных функций, она должна заканчиваться нулевым байтом, т. е. символом
с кодом 0.
Объявить строковую переменную в таком стиле можно двумя способами:
а) как указатель:
char *s;
В этом случае программист сам должен заботиться о выделении памяти под символы, составляющие строку.
Например, можно сделать это так:
s = new char[число_символов_строки+1];
Здесь +1 нужен для хранения завершающего строку нулевого символа. При использовании динамических массивов
нужно заботиться о своевременном их освобождении операцией delete.
Однако, такую переменную можно инициализировать строковой константой:
char *s = "текст_строки";
Такая возможность существует благодаря тому, что в C++ строковая константа — это просто указатель на первый
символ строки, заключенной в кавычки (завершающий нулевой символ добавляется автоматически компилятором).
Однако, обычно строковые константы хранятся в той части памяти, куда нельзя ничего записывать, так что у так
определенной строки нельзя менять входящие в ее состав символы. Если же мы хотим, чтобы содержимое строки
могло меняться, нужно пользоваться массивами (динамическими или обычными).
б) как массив:
char s[максимальное_число_символов+1];
Здесь память выделяется автоматически компилятором, и символы такой строки можно менять, но если этот
массив — локальная переменная, то надо быть готовым к тому, что он исчезнет по окончании работы содержащей его
функции. В частности, такие строки нельзя возвращать из той функции, в которой они определены (для этого нужно
пользоваться динамическими массивами).
Такая строка тоже может быть инициализирована, как традиционным для массивов образом (в этом случае завершающий символ с кодом 0 надо писать явно)
char s[число] = { ’H’, ’e’, ’l’, ’l’, ’o’, ’\0’ };
так и в сокращенной записи (завершающий нулевой символ добавляется автоматически компилятором)
char s[число] = "Hello";
Как и в случае массивов, указанное в квадратных скобках число элементов должно быть достаточным для записи
всех символов строки, включая завершающий символ с кодом 0. Если мы хотим, чтобы размер массива совпадал
с числом символов той строковой константы, которая в него записывается (включая завершающий 0), то число в
квадратных скобках можно опустить:
char s[] = "Hello";
Типы символов
В этом примере будет определен массив из шести символов.
Заголовочный файл cctype содержит набор весьма удобных макроопределений для проверки символа на принадлежность определенному классу.
Например, если c — символьная переменная, то условие isspace(c) будет истинно,
если c — пробельный символ. Таких макроопределений достаточно много, можно упомянуть несколько самых востребованных: isdigit — цифра и isalpha — латинская буква.
Здесь будет уместно следующее замечание: все эти макроопределения в случае, если ответ — ложь, возвращают
0, но если ответ — истина, они возвращают не 1, как можно было бы ожидать, а некоторое ненулевое число. Так что
вариант
if(isspace(c)) ...
будет работать, а вот такой код
if(isspace(c)==true) ...
— скорее всего, нет.
Доступ к отдельному символу
Как и для любого массива, доступ к символу из строки s по индексу (начинается с 0) выглядит как s[индекс].
Операции над строками
Для того, чтобы пользоваться библиотечными функциями для работы со строками, нужно подключить файл
cstring.
а) длина строки s дается функцией strlen(s)
б) к сожалению, строки в стиле C нельзя ни присваивать, ни сравнивать при помощи обычных операций сравнения.
Для копирования строк существует функция strcpy, принимающая два указателя на символы dest и src, и копирующая
строку, на которую указывает src, в область памяти, на которую указывает dest. Завершающий символ с кодом 0 тоже
копируется этой функцией автоматически.
Например, если нужно записать строку «Hello»в массив символов s, нужно написать
strcpy(s, "Hello");
Здесь нужно сделать два замечания. Во-первых, две строки, которыми оперирует strcpy, не должны перекрываться
в памяти. Например, такая попытка сдвинуть строку, удалив ее первый символ, незаконна:
strcpy(s, s+1);
Во-вторых, вся ответственность за то, чтобы в строке dest хватило памяти для записи строки src, всецело лежит на
программисте. Иногда такие ошибки ловит операционная система, но возможен и худший вариант, когда программа
молча выдает неверный ответ. Для надежности в этом плане существует функция strncpy, имеющая дополнительный
параметр (он идет последним), определяющий число копируемых символов. Если строка src короче, оставшиеся до
указанного числа символы заполняются нулями, но если она длиннее, то завершающий нулевой символ не пишется.
в) для сравнения строк используется функция strcmp. Ее параметрами будут сравниваемые строки, и она возвращает 0, если строки совпадают, отрицательное число, если первая строка меньше, и положительное, если она больше.
Так что для проверки равенства двух строк a и b нужно написать
strcmp(a, b)==0
а никак не a==b
По аналогии с strcpy, существует также вариант strncmp, сравнивающий только определенное количество начальных символов.
г) имеется также функция strcat с двумя строками-параметрами, приписывающая к строке, заданной первым
параметром, строку, заданную вторым. Как и в случае strcpy, строки-параметры не должны перекрываться, и наличие
достаточного количества памяти для приписывания — забота программиста. Имеется и вариант strncat; в отличие от
strncpy, нулевой завершающий символ приписывается к результату всегда, и если вторая строка короче указанного
числа символов, копируются только символы до завершающего включительно.
д) превращение строки s в целое число дается выражением atoi(s), в вещественное — atof(s). Обе эти функции объявлены в файле cstdlib. К сожалению, для обратного превращения числа в строку отдельных библиотечных функций
нет, и нужно пользоваться строковыми потоками.
е) ввод строки s c клавиатуры выполняется вызовом cin»s. При таком способе чтения строки все пробельные
символы считаются разделителями, так что строка читается до первого пробела. Кроме того, переполнение строки
никак не проверяется. Чтобы оно проверялось, надо написать
cin>>setw(число)>>s
В этом случае число-1 определяет максимальное количество считанных символов (-1 потому, что нужно записать
еще завершающий нулевой символ, так что в качестве параметра должен быть указан размер массива, содержащего
строку). Манипулятор setw объявлен в файле iomanip.
Считать строку до символа перевода строки (в том числе с пробелами) можно при помощи метода getline:
cin.getline(s, размер_массива)
Здесь важно сделать одно замечание: код
int x; char s[100];
cin>>x;
cin.getline(s, 100);
скорее всего, работать не будет. Если после ввода числа пользователь нажимает клавишу «ввод», то после чтения
числа символ перевода строки остается в потоке cin, и метод getline читает пустую строку.
Это можно исправить при
помощи манипулятора ws (пропуск пробельных символов):
int x; char s[100];
cin>>x>>ws;
cin.getline(s, 100);
Правда, при этом будут также пропущены все пробельные символы в начале той строки, которую мы собираемся
считывать, а если пользователь введет пустую строку (а еще хуже несколько), начнется хаос.
ж) для выделения подстроки следует использовать функцию strncpy со сдвинутым указателем src. Например,
выделить в массив dest подстроку строки src, начиная с символа с индексом 5 из 20 символов, можно так:
strncpy(dest, src+5, 20); dest[20] = 0;
з) найти первое вхождение символа c в строку s можно, написав
strchr(s, c)
Функция strchr возвращает указатель на первое вхождение символа в строку, или nullptr, если символ не входит в
строку.
Аналогично, найти последнее вхождение можно при помощи функции strrchr.
и) найти указатель на первый символ первого вхождения строки s1 в строку s2 можно при помощи вызова strstr(s2,
s1). Этот вызов имеет значение nullptr, если вхождений нет
Кроме простых указателей на символы или массивов символов, в C++ есть также библиотечный класс string
для хранения строк. Он медленнее работает, но предоставляет значительно больше удобств для работы со строками.
Например, в строках C++ нет явного признака конца строки, как в C, так что символ с кодом 0 вполне может
встречаться в строках типа string. Чтобы пользоваться этим типом, нужно включить в свою программу заголовочный
файл string:
#include <string>
string — класс с методами и переменными для организации работы со строками в языке программирования C++. Он включён в стандартную библиотеку C++. Название образовано от имени строчного типа данных (англ. string; с англ. — «строка»). В языке C++ и его предшественнике, языке программирования Си, нет встроенной поддержки строкового типа данных, вместо этого используется массив символов. string управляет строками, как и string.h в Си. string использует единственный объект string для организации работы со строками. Являясь частью стандартной библиотеки C++, эти объекты также являются частью стандартного пространства имён — std.
#include <iostream>
#include <string> // в Си: #include <string.h>
int main()
{
std::string str = "Hello, world!";
std::cout << str << std::endl; // в Си: puts(str);
return 0;
}
Строковые и символьные функции
Библиотека функций языков С и C++ включает богатый набор функций обработки строк и символов. Строковые функции работают с символьными массивами, завершающимися нулевыми символами. В языке С для использования строковых функций необходимо включить в начало модуля программы заголовочный файл <string.h>, а для символьных — заголовочный файл <ctype.h>. В языке C++ для работы со строковыми и символьными функциями используются заголовки <cstring> и <cctype.h> соответственно. В этой главе для простоты изложения используются имена С-заголовков.
Поскольку в языках С и C++ при выполнении операций с массивами не предусмотрен автоматический контроль нарушения их границ, вся ответственность за переполнение массивов ложится на плечи программиста. Пренебрежение этими тонкостями может привести программу к аварийному отказу.
В языках С и C++ печатаемыми являются символы, отображаемые на терминале. В ASCII-средах они расположены между пробелом(0x20) и тильдой(OxFE). Управляющие символы имеют значения, лежащие в диапазоне между нулем и Ox1F; к ним также относится символ DEL(Ox7F).
Исторически сложилось так, что аргументами символьных функций являются целые значения, из которых используется только младший байт. Символьные функции автоматически преобразуют свои аргументы в тип unsigned char. Безусловно, вы вольны вызывать эти функции с символьными аргументами, поскольку символы автоматически возводятся в ранг целых в момент вызова функции.
В заголовке <string.h> определен тип size_t, который является результатом применения оператора sizeof и представляет собой разновидность целого без знака.
В версии С99 к некоторым параметрам нескольких функций, первоначально определенных в версии С89, добавлен квалификатор restrict. При рассмотрении каждой такой функции будет приведен ее прототип, используемый в среде С89(а также в среде C++), а параметры с атрибутом restrict будут отмечены в описании этой функции.
Список функций
Проверка на принадлежность
isalnum — Проверка на принадлежность символа к алфавитно-цифровым
isalpha — Проверка на принадлежность символа к буквам
isblank — Проверка пустого символа
iscntrl — Проверка на принадлежность символа к управляющим
isdigit — Проверка на принадлежность символа к цифровым
isgraph — Проверка на принадлежность символа к печатным но не к пробелу
islower — Проверка на принадлежность символа к строчным
isprint — Проверка на принадлежность символа к печатным
ispunct — Проверка на принадлежность символа к знакам пунктуации
isspace — Проверка на принадлежность символа к пробельным
isupper — Проверка на принадлежность символа к прописным
isxdigit — Проверка на принадлежность символа к шестнадцатеричным
Работа с символьными массивами
memchr — Просматривает массив чтобы отыскать первое вхождение символа
memcmp — Сравнивает определённое количество символов в двух массивах
memcpy — Копирует символы из одного массива в другой
memmove — Копирует символы из одного массива в другой с учётом перекрытия массивов
memset — Заполняет определённое количество символов массива заданным
Манипуляции над строками
strcat — Присоединяет копию одной строки к заданной
strchr — Возвращает указатель на первое вхождение младшего байта заданного параметра
strcmp — Сравнивает в лексикографическом порядке две строки
strcoll — Сравнивает одну строку с другой в соответствии с параметром setlocale
strcpy — Копирует содержимое одной строки в другую
strcspn — Возвращает строку в которой отсутствуют заданные символы
strerror — Возвращает указатель на строку содержащую системное сообщение об ошибке
strlen — Возвращает длину строки с завершающим нулевым символом
strncat — Присоединяет определённое количество символов одной строки к другой
strncmp — Лексикографически сравнивает две строки
strncpy — Копирует определённое количество символов в символьный массив
strpbrk — Возвращает указатель на первый символ в строке который совпадает с заданными
strrchr — Возвращает указатель на последнее вхождение младшего байта заданного параметра в строке
strspn — Возвращает индекс первого символа в заданной строке, который не совпадает с любым из символов в другой строке
strstr — Возвращает указатель на первое вхождение одной строки в другую
strtok — Возвращает указатель на следующую лексему в строке
strxfrm — Преобразует определённое количество символов заданной строки чтобы ее можно было использовать функцией strcmp()
Другие функции
tolower — Переводит символ в нижний регистр
toupper — Переводит символ в верхний регистр
Не много примеров string
#include <iostream>
#include <string>
using namespace std;
int main() {
string S;
cout << "Введите строку:";
getline(cin, S);
size_t s = S.find(' ');
size_t e = S.rfind(' ');
string subS1 = S.substr(0, s);
string subS2 = S.substr(e + 1, string::npos);
S.replace(0, subS1.size(), subS2);
e = S.rfind(' ');
S.replace(e + 1, subS2.size(), subS1);
cout << S << endl;
return 0;
}
Рассмотрим пример. Дана строка S1. Эта строка делится пополам. Первая половина строки помещается в строку S2, а вторая – в строку S3. Заменить исходную строку на строку, состоящую из 20 символов '*'. Вывести строки S1, S2 и S3. Изменить строки S1 и S2 так, чтобы первые семь символов строки S2 и последние семь символов строки S3 были заменены на символы строки S1. Вывести модифицированные строки S2 и S3.
#include <iostream>
#include <string>
using namespace std;
int main() {
string S1("The C++ programming language has support for string handling, "
"mostly implemented in its standard library."
);
auto first = S1.cbegin();
auto last = S1.cend();
// Используем итераторы
string S2(first, last - S1.size() / 2);
string S3(first + S1.size() / 2, last);
cout << "S1 => " << S1 << endl;
S1.assign(20, '*');
cout << "S2 => " << S2 << "\n"
<< "S3 => " << S3 << "\n"
<< "S1 => " << S1 << endl;
// Используем диапазоны
S2.replace(0, 7, S1);
S3.replace(S3.size() - 7, 7, S1);
cout << "S2 => " << S2 << "\n"
<< "S3 => " << S3 << endl;
return 0;
}
Подробно о классе STRING
#include <string>
Не путайте с подключением Си-совместимой библиотеки для работы со строками char *:
#include <string.h>
или
#include <cstring>
Для работы со строками также нужно подключить стандартный namespace:
using namespace std;
В противном случае придётся везде указывать описатель класса std::string вместо string.
Ниже приводится пример программы, работающей со string (в старых си-совместимых компиляторах не работает!):
#include <iostream>
#include <string>
#include <malloc.h>
using namespace std;
int main () {
string s = "Test";
s.insert (1,"!");
cout << s.c_str() << endl;
string *s2 = new string("Hello");
s2->erase(s2->end());
cout << s2->c_str();
cin.get(); return 0;
}
Основные возможности, которыми обладает класс string:
инициализация массивом символов (строкой встроенного типа) или другим объектом типа string. Встроенный тип не обладает второй возможностью;
копирование одной строки в другую. Для встроенного типа приходится использовать функцию strcpy();
доступ к отдельным символам строки для чтения и записи. Во встроенном массиве для этого применяется операция взятия индекса или косвенная адресация с помощью указателя;
сравнение двух строк на равенство. Для встроенного типа используются функции семейства strcmp();
конкатенация (сцепление) двух строк, дающая результат либо как третью строку, либо вместо одной из исходных. Для встроенного типа применяется функция strcat(), однако чтобы получить результат в новой строке, необходимо последовательно задействовать функции strcpy() и strcat(), а также позаботиться о выделении памяти;
встроенные средства определения длины строки (функции-члены класса size() и length()). Узнать длину строки встроенного типа можно только вычислением с помощью функции strlen();
возможность узнать, пуста ли строка.
Рассмотрим эти базовые возможности более подробно.
Инициализация строк при описании и длина строки (не включая завершающий нуль-терминатор):
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;
Но лучше читать документацию по C++ и пользоваться его возможностями. Например, предыдущее действие мы могли бы выполнить вызовом одной-единственной функции replace():
replace( str.begin(), str.end(), '.', '_' );
Правда, здесь использован не метод replace класса string, а одноимённый алгоритм:
#include <algorithm>
Поскольку объект string ведет себя как контейнер, к нему могут применяться и другие алгоритмы. Это позволяет решать задачи, не решаемые напрямую функциями класса string.
Ниже приводится краткое описание основных операторов и функций класса string, ссылки в таблице ведут к русскоязычным описаниям в интернете. Более полный список возможностей класса string можно получить, например, в Википедии или на сайте cplusplus.com.
Задание символов в строке
operator=
присваивает значения строке
assign
назначает символы строке
Доступ к отдельным символам
at
получение указанного символа с проверкой выхода индекса за границы
operator[]
получение указанного символа
front
получение первого символа
back
получение последнего символа
data
возвращает указатель на первый символ строки
c_str
возвращает немодифицируемый массив символов С, содержащий символы строки
Проверка на вместимость строки
empty
проверяет, является ли строка пустой
size
length
возвращает количество символов в строке
max_size
возвращает максимальное количество символов
reserve
резервирует место под хранение
Операции над строкой
clear
очищает содержимое строки
insert
вставка символов
erase
удаление символов
push_back
добавление символа в конец строки
pop_back
удаляет последний символ
append
добавляет символы в конец строки
operator+=
добавляет символы в конец строки
compare
сравнивает две строки
replace
заменяет каждое вхождение указанного символа
substr
возвращает подстроку
copy
копирует символы
resize
изменяет количество хранимых символов
swap
обменивает содержимое
Поиск в строке
find
поиск символов в строке
rfind
поиск последнего вхождения подстроки
find_first_of
поиск первого вхождения символов
find_first_not_of
найти первое вхождение отсутствия символов
find_last_of
найти последнее вхождение символов
find_last_not_of
найти последнее вхождение отсутствия символов
Следует обратить внимание, что у любой функции класса string может быть несколько перегрузок - разновидностей с одинаковыми именами, отличающихся между собой списками и типами аргументов.
В качестве недостатков класса string можно отметить следующее:
отсутствие в классе встроенных средств для разбора строк по набору разделителей (аналога функции strtok для строк char *);
возможное замедление быстродействия по отношению к char * при сложной обработке данных.
Ниже приведён код для разбора введённой с клавиатуры строки string на слова. Можно доработать этот код, исключив знаки препинания, стоящие последними символами строк vecstr[i], а также слова, не содержащие ни одного алфавитно-цифрового символа.
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main() {
cout << "Enter the string: ";
string str;
getline(cin, str);
vector <string> vecstr;
string word;
stringstream s(str);
while (s >> word) vecstr.push_back(word);
int vsize = vecstr.size();
for (int i = 0; i < vsize; i++)
cout << vecstr[i] << endl;
cin.get();
return 0;
}
Пример своего класса STRING Что такое Class OOP C++ Читайте в разделе -> Выбор темы <-
#ifndef STRING_H
#define STRING_H
#include <iostream>
namespace STD
{
int StrLen(char*);
void StrCpy(char*, char*);
bool StrCmp(char*, char*);
class String
{
public:
String(char* _str = "");
String(const String&);
~String();
String& operator=(const String&);
friend String operator+(const String&, const String&);
String& operator+=(const String&);
friend bool operator==(const String&, const String&);
friend bool operator!=(const String&, const String&);
friend bool operator>(const String&, const String&);
friend bool operator>=(const String&, const String&);
friend bool operator<(const String&, const String&);
friend bool operator<=(const String&, const String&);
const char& operator[](int) const;
char& operator[](int);
friend std::ostream& operator<<(std::ostream&, const String&);
friend std::istream& operator>>(std::istream&, String&);
private:
char* str;
};
String::String(char* _str)
{
str = new char[StrLen(_str)+1];
StrCpy(str, _str);
}
String::String(const String& rhs)
{
str = new char[StrLen(rhs.str)+1];
StrCpy(str, rhs.str);
}
String::~String()
{
delete str;
}
// ---
String& String::operator=(const String& rhs)
{
if (this != &rhs)
{
delete[] this->str;
this->str = new char[StrLen(rhs.str)+1];
StrCpy(this->str, rhs.str);
}
return *this;
}
String& String::operator+=(const String& rhs)
{
int sz = StrLen(this->str) + StrLen(rhs.str);
char* ts = new char[sz+1];
for (int i = 0; i < StrLen(this->str); i++)
ts[i] = this->str[i];
for (int ii = StrLen(this->str), j = 0; ii <= sz; ii++, j++)
ts[ii] = rhs.str[j];
delete this->str;
this->str = ts;
return *this;
}
String operator+(const String& lhs, const String& rhs)
{
String ts = lhs;
return ts += rhs;
}
// --
bool operator==(const String& lhs, const String& rhs)
{
return StrCmp(lhs.str, rhs.str);
}
bool operator!=(const String& lhs, const String& rhs)
{
return !(StrCmp(lhs.str, rhs.str));
}
bool operator>(const String& lhs, const String& rhs)
{
return (StrLen(lhs.str) > StrLen(rhs.str)) ? true : false;
}
bool operator>=(const String& lhs, const String& rhs)
{
return (StrLen(lhs.str) >= StrLen(rhs.str)) ? true : false;
}
bool operator<(const String& lhs, const String& rhs)
{
return (StrLen(lhs.str) < StrLen(rhs.str)) ? true : false;
}
bool operator<=(const String& lhs, const String& rhs)
{
return (StrLen(lhs.str) <= StrLen(rhs.str)) ? true : false;
}
// ---
const char& String::operator[](int i) const
{
//std::cerr << "Index out of range. \n";
return (i >= 0 && i < StrLen(this->str)) ? this->str[i] : 0;
}
char& String::operator[](int i)
{
static char DUMMY; DUMMY = '';
//std::cerr << "Index out of range. \n";
return (i >= 0 && i < StrLen(this->str)) ? this->str[i] : DUMMY;
}
// ---
std::ostream& operator<<(std::ostream& os, const String& obj)
{
return os << obj.str;
}
std::istream& operator>>(std::istream& is, String& obj)
{
char BUFF[2048];
is.getline(BUFF, sizeof BUFF);
obj = BUFF;
return is;
}
// ---
int StrLen(char* _str)
{
int size = 0;
for (; _str[size] != 0; size++);
return size;
}
void StrCpy(char* in_str, char* src_str)
{
for (int i = 0; i < StrLen(in_str); i++)
in_str[i] = src_str[i];
}
bool StrCmp(char* str_f, char* str_s)
{
int i = 0;
for (; str_f[i] == str_s[i] && i < StrLen(str_f); i++);
return (i == StrLen(str_f)) ? true : false;
}
}
#endif
Таблица ASCII

Consider below two statements in C. What is the difference between the two?
char s[] = "geeksquiz"; char *s = "geeksquiz";
Below are the key differences:
The statements ‘char s[] = “geeksquiz”‘ creates a character array which is like any other array and we can do all array operations. The only special thing about this array is, although we have initialized it with 9 elements, its size is 10 (Compiler automatically adds ‘\0’)
C
#include <stdio.h>
int main()
{
char s[] = "geeksquiz";
printf("%lu", sizeof(s));
s[0] = 'j';
printf("\n%s", s);
return 0;
}
Output
10 jeeksquiz
The statement ‘char *s = “geeksquiz”‘ creates a string literal. The string literal is stored in the read-only part of memory by most of the compilers. The C and C++ standards say that string literals have static storage duration, any attempt at modifying them gives undefined behavior.
s is just a pointer and like any other pointer stores address of string literal.
C
#include <stdio.h>
int main()
{
char *s = "geeksquiz";
printf("%lu", sizeof(s));
return 0;
}
Output
8
Running above program may generate a warning also “warning: deprecated conversion from string constant to ‘char*’”. This warning occurs because s is not a const pointer, but stores address of the read-only location. The warning can be avoided by the pointer to const.
C
#include <stdio.h>
int main()
{
const char *s = "geeksquiz";
printf("%lu", sizeof(s));
return 0;
}
Output
8
Whether you’re preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape, GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we’ve already empowered, and we’re here to do the same for you. Don’t miss out — check it out now!
Last Updated :
14 Sep, 2023
Like Article
Save Article
Си работа со строками
Объявление строк
Строка в языке Си представляет собой одномерный массив символов, последним элементом которой является символ конца строки – нуль (строка, завершающаяся нулем, то есть NULL terminated string).
Объявление переменной типа строка в языке Си возможно тремя способами, два из которых инициализируют строку во время объявления.
Первый способ:
Объявления массива символов (не забудьте добавить место для завершающего нуля):
char s[40+1];
Второй способ:
Присвоить строковой переменной начальное значение (при этом длину строки компилятор может вычислить сам):
char s[] = "Пример инициализации строки";
Справа от знака присваивания записана строковая константа. В конце строки автоматически добавляется ноль (‘\0’). Константы символьных строк помещаются в класс статической памяти.
Третий способ:
Неявное указание, что используется массив. В левой части от знака присваивания указывается указатель на символ:
char *s="Второй вариант инициализации";
Переменная s будет указателем на то место в оперативной памяти, где располагается строковая константа. В такой форме записи кроется потенциальная ошибка, заключающаяся в том, что указатель на символ часто называют строкой. Представленная ниже запись – это только указатель на символ, так как для размещения строки место не предусмотрено:
char *s;
Ввод строки со стандартного устройства ввода (клавиатуры)
Для работы со строками есть набор функций. Для ввода со стандартного устройства ввода (клавиатуры) чаще всего используются библиотечные функциями из модуля стандартного ввода-вывода: scanf и gets.
Для ввода строки с помощью функции scanf, использует формат «%s», причем обратите внимание на то, что перед идентификатором строки не используется знак адреса «&», так как одномерный массив уже представлен указателем на его начало:
scanf("%s", s);
Функция gets() считывает символы до тех пор, пока не достигнет символа перехода на новую строку. Функция принимает все символы вплоть до символа перевода строки, но не включает его. К концу строки добавляется завершающий ноль (‘\0’). Функция gets() помещает считанную с клавиатуры последовательность символов в параметр типа строка и возвращает указатель на эту строку (если операция завершилась успешно), или NULL (в случае ошибки). В приведенном ниже примере при успешном завершении операции, на экран будет выведено две одинаковые строки:
#include <stdio.h>
int main()
{ char s[50];
char *p;
p=gets(s);
printf(" \n Введена строка %s. ",s);
if (p) printf(" \n Введена строка %s. ",p);
return 0;
}
Попутно заметим, что функция gets часто используется для ввода лю-бых данных с клавиатуры в виде строки с целью дальнейшего преобразования функцией sscanf к нужному формату или для предварительного анализа вводимых данных, например:
#include <string.h>
#include <stdio.h>
#include <conio.h>
int main()
{ char s[50]; int x, err;
do
{ printf(" \n Введите целое число -> ");
gets(s);
err=sscanf(s, "%d",&x);
if (err!=1) printf(" \n Ошибка ввода. ");
} while (err!=1);
printf("\n Введено целое число -> %d", x);
return 0;
}
Вывод строк на стандартное устройство вывода (экран монитора)
Для вывода строк на стандартное устройство вывода (экран монитора) можно использовать две функции printf и puts. В функции printf в качестве формата передается «%s». Удобство использования этой функции заключается в том, что помимо строки можно сразу выводит данные других типов. Особенность функции puts заключается в том, что после вывода строки автоматически происходит переход на следующую строку.
Функции для работы со строками
Для преобразования строк в языке Си предусмотрена библиотека string. Каждая из функций имеет свой формат записи (прототип).
Наиболее используемые функции рассмотрены в этой статье. — читать
Пример программ(листинг) работающей со строками
Пример №1(листинг) | Пример№2 (Листинг)





