C string что это: C++. Работа со строками. Класс string
Строки в языке C++ (класс string)
Строки в языке C++ (класс string)
В языке C++ для удобной работы со строками есть класс string, для использования которого необходимо подключить заголовочный файл string.
Строки можно объявлять и одновременно присваивать им значения:
Строка S1 будет пустой, строка S2 будет состоять из 5 символов.
К отдельным символам строки можно обращаться по индексу, как к элементам массива или C-строк. Например S[0] — это первый символ строки.
Для того, чтобы узнать длину строки можно использовать метод size() строки. Например, последний символ строки S это S[S.size() — 1].
Строки в языке C++ могут
Конструкторы строк
Строки можно создавать с использованием следующих конструкторов:string()
— конструктор по умолчанию (без параметров) создает пустую строку.string(string & S)
— копия строки S
string(
— повторение символа size_t
n, char c)c
заданное число n
раз.string(size_t c)
— строка из одного символа c
.string(string & S,
size_t
start,
— строка, содержащая не более, чем size_t
len)len
символов данной строки S
, начиная с символа номер start
.
Конструкторы можно вызывать явно, например, так:
В этом примере явно вызывается конструктор string
для создания строки, состоящей из 10 символов 'z'
.
Неявно конструктор вызывается при объявлении строки с указанием дополнительных параметров. Например, так:
Подробней о конструкторах для строк читайте здесь.
Ввод-вывод строк
Строка выводится точно так же, как и числовые значения:
Для считывания строки можно использовать операцию «>>» для объекта cin:
В этом случае считывается строка из непробельных символов, пропуская пробелы и концы строк. Это удобно для того, чтобы разбивать текст на слова, или чтобы читать данные до конца файла при помощи while (cin >> S).
Можно считывать строки до появления символа конца строки при помощи функции getline. Сам символ конца строки считывается из входного потока, но к строке не добавляется:
Арифметические операторы
Со строками можно выполнять следующие арифметические операции:=
— присваивание значения.+=
— добавление в конец строки другой строки или символа.+
— конкатенация двух строк, конкатенация строки и символа.==
, !=
— посимвольное сравнение.<
, >
, <=
, >=
— лексикографическое сравнение.
То есть можно скопировать содержимое одной строки в другую при помощи операции S1 = S2, сравнить две строки на равенство при помощи S1 == S2, сравнить строки в лексикографическом порядке при помощи S1 < S2, или сделать сложение (конкатенацию) двух строк в виде S = S1 + S2.
Подробней об операторах для строк читайте здесь.
Методы строк
У строк есть разные методы, многие из них можно использовать несколькими разными способами (с разным набором параметров).
Рассмотрим эти методы подробней.
size
Метод size() возращает длину длину строки. Возвращаемое значение является беззнаковым типом (как и во всех случаях, когда функция возращает значение, равное длине строке или индексу элемента — эти значения беззнаковые). Поэтому нужно аккуратно выполнять операцию вычитания из значения, которое возвращает size(). Например, ошибочным будет запись цикла, перебирающего все символы строки, кроме последнего, в виде for (int i = 0; i < S.size() — 1; ++i).
Кроме того, у строк есть метод length(), который также возвращает длину строки.
Подробней о методе size.
resize
S.resize(n) — Изменяет длину строки, новая длина строки становится равна n. При этом строка может как уменьшится, так и увеличиться. Если вызвать в виде S.resize(n, c), где c — символ, то при увеличении длины строки добавляемые символы будут равны c.
Подробней о методе resize.
clear
S.clear() — очищает строчку, строка становится пустой.
Подробней о методе clear.
empty
S.empty() — возвращает true, если строка пуста, false — если непуста.
Подробней о методе empty.
push_back
S.push_back(c) — добавляет в конец строки символ c, вызывается с одним параметром типа char.
Подробней о методе push_back.
append
Добавляет в конец строки несколько символов, другую строку или фрагмент другой строки. Имеет много способов вызова.
S.append(n, c) — добавляет в конец строки n одинаковых символов, равных с. n имеет целочисленный тип, c — char.
S.append(T) — добавляет в конец строки S содержимое строки T. T может быть объектом класса string или C-строкой.
S.append(T, pos, count) — добавляет в конец строки S символы строки T начиная с символа с индексом pos количеством count.
Подробней о методе append.
erase
S.erase(pos) — удаляет из строки S с символа с индексом pos и до конца строки.
S.erase(pos, count) — удаляет из строки S с символа с индексом pos количеством count или до конца строки, если pos + count > S.size().
Подробней о методе erase.
insert
Вставляет в середину строки несколько символов, другую строку или фрагмент другой строки. Способы вызова аналогичны способам вызова метода append, только первым параметром является значение i — позиция, в которую вставляются символы. Первый вставленный символ будет иметь индекс i, а все символы, которые ранее имели индекс i и более сдвигаются вправо.
S.insert(i, n, c) — вставить n одинаковых символов, равных с. n имеет целочисленный тип, c — char.
S.insert(i, T) — вставить содержимое строки T. T может быть объектом класса string или C-строкой.
S.insert(i, T, pos, count) — вставить символы строки T начиная с символа с индексом pos количеством count.
Подробней о методе insert.
substr
S.substr(pos) — возвращает подстроку данной строки начиная с символа с индексом pos и до конца строки.
S.substr(pos, count) — возвращает подстроку данной строки начиная с символа с индексом pos количеством count или до конца строки, если pos + count > S.size().
Подробней о методе substr.
replace
Заменяет фрагмент строки на несколько равных символов, другую строку или фрагмент другой строки. Способы вызова аналогичны способам вызова метода append, только первыми двумя параметрами являются два числа: pos и count. Из данной строки удаляется count символов, начиная с символа pos, и на их место вставляются новые символы.
S.replace(pos, count, n, c) — вставить n одинаковых символов, равных с. n имеет целочисленный тип, c — char.
S.replace(pos, count, T) — вставить содержимое строки T. T может быть объектом класса string или C-строкой.
S.replace(pos, count, T, pos2, count2) — вставить символы строки T начиная с символа с индексом pos количеством count.
Подробней о методе replace.
find
Ищет в данной строке первое вхождение другой строки str. Возвращается номер первого символа, начиная с которого далее идет подстрока, равная строке str. Если эта строка не найдена, то возвращается константа string::npos (которая равна -1, но при этом является беззнаковой, то есть на самом деле является большим безннаковым положительным числом).
Если задано значение pos, то поиск начинается с позиции pos, то есть возращаемое значение будет не меньше, чем pos. Если значение pos не указано, то считается, что оно равно 0 — поиск осуществляется с начала строки.
S.find(str, pos = 0) — искать первое входение строки str начиная с позиции pos. Если pos не задано — то начиная с начала строки S.
S.find(str, pos, n) — искать в данной строке подстроку, равную первым n символам строки str. Значение pos должно быть задано.
Подробней о методе find.
rfind
Ищет последнее вхождение подстроки («правый» поиск). Способы вызова аналогичны способам вызова метода find.
Подробней о методе rfind.
find_first_of
Ищет в данной строке первое появление любого из символов данной строки str. Возвращается номер этого символа или значение string::npos.
Если задано значение pos, то поиск начинается с позиции pos, то есть возращаемое значение будет не меньше, чем pos. Если значение pos не указано, то считается, что оно равно 0 — поиск осуществляется с начала строки.
S.find_first_of(str, pos = 0) — искать первое входение любого символа строки str начиная с позиции pos. Если pos не задано — то начиная с начала строки S.
Подробней о методе find_first_of.
find_last_of
Ищет в данной строке последнее появление любого из символов данной строки str. Способы вызова и возвращаемое значение аналогичны методу find_first_of.
Подробней о методе find_last_of.
find_first_not_of
Ищет в данной строке первое появление символа, отличного от символов строки str. Способы вызова и возвращаемое значение аналогичны методу find_first_of.
Подробней о методе find_first_not_of.
find_last_not_of
Ищет в данной строке последнее появление символа, отличного от символов строки str. Способы вызова и возвращаемое значение аналогичны методу find_first_of.
Подробней о методе find_last_not_of.
c_str
Возвращает указать на область памяти, в которой хранятся символы строки, возвращает значение типа char*. Возвращаемое значение можно рассматривать как C-строку и использовать в функциях, которые должны получать на вход C-строку.
Подробней о методе c_str.
В чем разница между String и String в C#?
Просто для полноты картины, вот свалка соответствующей информации…
как уже отмечалось, string
псевдоним System.String
. Они компилируются в один и тот же код, поэтому во время выполнения, разницы нет. Это всего лишь один из псевдонимов в C#. Полный список:
object: System.Object
string: System.String
bool: System.Boolean
byte: System.Byte
sbyte: System.SByte
short: System.Int16
ushort: System.UInt16
int: System.Int32
uint: System.UInt32
long: System.Int64
ulong: System.UInt64
float: System.Single
double: System.Double
decimal: System.Decimal
char: System.Char
помимо string
и object
, псевдонимы все для типов значений. decimal
является типом значения, но не примитивным типом в среде CLR. Единственный примитив тип, у которого нет псевдонима, —System.IntPtr
.
в спецификации псевдонимы типов значений известны как»простые типы». Литералы можно использовать для постоянных значений каждого простого типа; никакие другие типы значений не имеют доступных литеральных форм. (Сравните это с VB, который позволяет DateTime
литералы, и имеет псевдоним для него тоже.)
есть одно обстоятельство, при котором вы есть использовать псевдонимы: при явном указании базового типа перечисления. Для пример:
public enum Foo : UInt32 {} // Invalid
public enum Bar : uint {} // Valid
это просто вопрос того, как спецификация определяет объявления перечисления-часть после двоеточия должна быть Интеграл-типа производство, которое является одним из символов sbyte
, byte
, short
, ushort
, int
, uint
, long
, ulong
, char
… в отличие от тип производства как объявления переменных например. Это не указывает на какую-либо другую разницу.
наконец, когда дело доходит до что использовать: лично я использую псевдонимы везде для реализации, но тип CLR для любых API. На самом деле не имеет большого значения, что вы используете с точки зрения реализации — согласованность среди вашей команды хороша, но никто другой не будет заботиться. С другой стороны, действительно важно, что если вы ссылаетесь на тип в API, вы делаете это нейтральным языком. Метод называется ReadInt32
является однозначным, тогда как метод называется ReadInt
требует интерпретации. Звонивший может быть использование языка, который определяет int
псевдоним Int16
, например. Дизайнеры .NET framework следовали этому шаблону, хорошие примеры были в BitConverter
, BinaryReader
и Convert
классы.
string str1 = «Hello»; int v1 = str1.Length;
C# (язык программирования)
Новое приложение для изучения C#
Отладка кода
Типы данных C#
• C# типы данных: число (bool, char, byte, int, long, float, double, decimal), текст (string), перечисление (enum), класс (class), структура (struct)
Хранение объектов в памяти. Удаление объектов из памяти
C# конвертация типов
Текст в C# (тип string и класс String)
Перечисления в C# (enum)
null
try-catch
Классы в C# (class)
Конструкторы для класса
Деструкторы для класса
Наследование
Наследование с использованием new
Наследование с использованием sealed
Абстрактный класс
Константы и readonly поля в классе
Свойства get и set в классе C# (аксессоры)
Операторы, индексаторы в C#
Вложенные типы в C#
Параметры в методе класса C#
Универсальные методы, универсальные классы в C# (шаблоны)
Преобразование объекта класса из одного типа в другой
Объект класса в C#
Статический конструктор и статические свойства и методы
Дополнительные возможности класса в C#
Правила именования классов в C#
Статический класс
Анонимный класс
Интерфейсы
Структура struct
Преобразование объекта структуры из одного типа в другой
Отложенная загрузка class Lazy в C#
Кортежи (tuple)
Динамические объекты с любыми свойствами
Массивы
Коллекции
• Что такое обобщенные (типизированные) коллекции в C# ? Классы List<T>, SortedList<T>, Stack<T>, Dictionary<TKey,TValue>, LinkedList<T>, Queue<T>, HashSet<T>, SortedSet<T>, ConcurrentDictionary<TKey, TValue>, SortedDictionary<TKey, TValue>
Классы необобщенных коллекций (в одной коллекции хранятся элементы разного типа)
Класс ArrayList (коллекция в C#)
Класс SortedList (коллекция в C#)
Класс Stack (коллекция в C#)
Класс Queue (коллекция в C#)
Класс Hashtable (коллекция в C#)
Класс BitArray (коллекция в C#)
Классы обобщенных, типизированных коллекций в C# (в одной коллекции хранятся элементы одного типа)
Класс List<T> (типизированная коллекция в C#)
Класс LinkedList<T> (типизированная коллекция в C#)
Класс SortedList<TKey, TValue> (типизированная коллекция в C#)
Класс Stack<T> (типизированная коллекция в C#)
Класс Queue<T> (типизированная коллекция в C#)
Класс HashSet<T> (типизированная коллекция в C#)
Класс SortedSet<T> (типизированная коллекция в C#)
Класс ObservableCollection<T> (типизированная коллекция в C#)
Класс Dictionary<TKey, TValue> (типизированная коллекция в C#)
Класс SortedDictionary<TKey, TValue> (типизированная коллекция в C#)
Класс ConcurrentDictionary<TKey, TValue> (типизированная коллекция в C#)
Асимптотическая сложность для добавления, удаления, взятия элемента в коллекциях
• Асимптотическая сложность для добавления, удаления, взятия элемента в коллекциях C# (List, SortedList, Stack, Dictionary, LinkedList, Queue, HashSet, SortedSet, ConcurrentDictionary, SortedDictionary)
Сортировка элементов в массиве [] и коллекции List
Моя реализация IEnumerator, IEnumerable и итераторы
Методы расширения для IEnumerable (поиск, замена, выборка значений) в C#
Сортировка, фильтрация в LINQ (Language-Integrated Query)
Указатели
Работа с файлами
Сериализация
Пространства имен
Delegate
Универсальные делегаты
События
Лямда
Регулярные выражения
Процесс, модули процесса
Потоки, многопоточность
Parallel Library Task (TPL) Параллельное программирование задач
Асинхронные методы (async и await)
Домены приложений
Атрибуты
Рефлексия (отражение) reflection в C#
Директивы препроцессора (if при компиляции)
Что такое сборка и исполняющая среда CLR ?
Создание и подключение нашей сборки
▷
База данных (Entity Framework) в консольном приложении C#
Внедрение зависимостей (Dependency Injection) DI в C#
Удобные утилиты Visual Studio
В приложении C# вызываем C++ функции
Дополнительные темы, вопросы
Математические операторы checked и unchecked
Дополнительный C# классы
Время
WWW сайты для изучения C#
string str1 = «Hello World!»; string str2 = str1.Substring(2, 5);
C# (язык программирования)
Новое приложение для изучения C#
Отладка кода
Типы данных C#
• C# типы данных: число (bool, char, byte, int, long, float, double, decimal), текст (string), перечисление (enum), класс (class), структура (struct)
Хранение объектов в памяти. Удаление объектов из памяти
C# конвертация типов
Текст в C# (тип string и класс String)
Перечисления в C# (enum)
null
try-catch
Классы в C# (class)
Конструкторы для класса
Деструкторы для класса
Наследование
Наследование с использованием new
Наследование с использованием sealed
Абстрактный класс
Константы и readonly поля в классе
Свойства get и set в классе C# (аксессоры)
Операторы, индексаторы в C#
Вложенные типы в C#
Параметры в методе класса C#
Универсальные методы, универсальные классы в C# (шаблоны)
Преобразование объекта класса из одного типа в другой
Объект класса в C#
Статический конструктор и статические свойства и методы
Дополнительные возможности класса в C#
Правила именования классов в C#
Статический класс
Анонимный класс
Интерфейсы
Структура struct
Преобразование объекта структуры из одного типа в другой
Отложенная загрузка class Lazy в C#
Кортежи (tuple)
Динамические объекты с любыми свойствами
Массивы
Коллекции
• Что такое обобщенные (типизированные) коллекции в C# ? Классы List<T>, SortedList<T>, Stack<T>, Dictionary<TKey,TValue>, LinkedList<T>, Queue<T>, HashSet<T>, SortedSet<T>, ConcurrentDictionary<TKey, TValue>, SortedDictionary<TKey, TValue>
Классы необобщенных коллекций (в одной коллекции хранятся элементы разного типа)
Класс ArrayList (коллекция в C#)
Класс SortedList (коллекция в C#)
Класс Stack (коллекция в C#)
Класс Queue (коллекция в C#)
Класс Hashtable (коллекция в C#)
Класс BitArray (коллекция в C#)
Классы обобщенных, типизированных коллекций в C# (в одной коллекции хранятся элементы одного типа)
Класс List<T> (типизированная коллекция в C#)
Класс LinkedList<T> (типизированная коллекция в C#)
Класс SortedList<TKey, TValue> (типизированная коллекция в C#)
Класс Stack<T> (типизированная коллекция в C#)
Класс Queue<T> (типизированная коллекция в C#)
Класс HashSet<T> (типизированная коллекция в C#)
Класс SortedSet<T> (типизированная коллекция в C#)
Класс ObservableCollection<T> (типизированная коллекция в C#)
Класс Dictionary<TKey, TValue> (типизированная коллекция в C#)
Класс SortedDictionary<TKey, TValue> (типизированная коллекция в C#)
Класс ConcurrentDictionary<TKey, TValue> (типизированная коллекция в C#)
Асимптотическая сложность для добавления, удаления, взятия элемента в коллекциях
• Асимптотическая сложность для добавления, удаления, взятия элемента в коллекциях C# (List, SortedList, Stack, Dictionary, LinkedList, Queue, HashSet, SortedSet, ConcurrentDictionary, SortedDictionary)
Сортировка элементов в массиве [] и коллекции List
Моя реализация IEnumerator, IEnumerable и итераторы
Методы расширения для IEnumerable (поиск, замена, выборка значений) в C#
Сортировка, фильтрация в LINQ (Language-Integrated Query)
Указатели
Работа с файлами
Сериализация
Пространства имен
Delegate
Универсальные делегаты
События
Лямда
Регулярные выражения
Процесс, модули процесса
Потоки, многопоточность
Parallel Library Task (TPL) Параллельное программирование задач
Асинхронные методы (async и await)
Домены приложений
Атрибуты
Рефлексия (отражение) reflection в C#
Директивы препроцессора (if при компиляции)
Что такое сборка и исполняющая среда CLR ?
Создание и подключение нашей сборки
▷
База данных (Entity Framework) в консольном приложении C#
Внедрение зависимостей (Dependency Injection) DI в C#
Удобные утилиты Visual Studio
В приложении C# вызываем C++ функции
Дополнительные темы, вопросы
Математические операторы checked и unchecked
Дополнительный C# классы
Время
WWW сайты для изучения C#
.net — В чем разница между String и String в C #?
Переполнение стека
- Около
Продукты
- Для команд
Переполнение стека
Общественные вопросы и ответыПереполнение стека для команд
Где разработчики и технологи делятся частными знаниями с коллегамиВакансии
Программирование и связанные с ним технические возможности карьерного ростаТалант
Нанимайте технических специалистов и создавайте свой бренд работодателяРеклама
Обратитесь к разработчикам и технологам со всего мира- О компании
Загрузка…
.
c ++ — String :: New: что это?
Переполнение стека
- Около
Продукты
- Для команд
Переполнение стека
Общественные вопросы и ответыПереполнение стека для команд
Где разработчики и технологи делятся частными знаниями с коллегамиВакансии
Программирование и связанные с ним технические возможности карьерного ростаТалант
Нанимайте технических специалистов и создавайте свой бренд работодателяРеклама
Обратитесь к разработчикам и технологам со всего мира- О компании
Загрузка…
.
6.6 — Струны в стиле С | Изучите C ++
В уроке 4.4b — Введение в std :: string мы определили строку как набор последовательных символов, таких как «Hello, world!». Строки — это основной способ работы с текстом в C ++, а std :: string упрощает работу со строками в C ++.
Современный C ++ поддерживает два разных типа строк: std :: string (как часть стандартной библиотеки) и строки в стиле C (изначально унаследованные от языка C). Оказывается, std :: string реализован с использованием строк в стиле C.В этом уроке мы подробнее рассмотрим струны в стиле C.
Струны в стиле C
Строка в стиле C — это просто массив символов, в котором используется нулевой терминатор. Знак конца строки . — это специальный символ («\ 0», код ascii 0), используемый для обозначения конца строки. В более общем смысле, строка в стиле C называется строкой с завершающим нулем .
Чтобы определить строку в стиле C, просто объявите массив символов и инициализируйте его строковым литералом:
char myString [] {«строка»}; |
Хотя «строка» состоит только из 6 букв, C ++ автоматически добавляет нулевой терминатор в конец строки для нас (нам не нужно включать его самим).Следовательно, myString на самом деле представляет собой массив длиной 7!
Доказательство этого можно увидеть в следующей программе, которая распечатывает длину строки, а затем значения ASCII всех символов:
1 2 3 4 5 6 7 8 9 10 11 12 13 140002 14 | #include #include int main () { char myString [] {«строка»}; const int length {static_cast // const int length {sizeof (myString) / sizeof (myString [0])}; // вместо этого используйте, если не поддерживает C ++ 17 std :: cout << myString << "имеет символы" << length << ".\ n "; для (int index {0}; index std :: cout << static_cast std :: cout << '\ n'; return 0; } |
Это дает результат:
строка состоит из 7 символов. 115 116 114 105 110 103 0
0 — это код ASCII нулевого терминатора, добавленного в конец строки.
При объявлении строк таким образом рекомендуется использовать [] и позволить компилятору вычислить длину массива. Таким образом, если вы измените строку позже, вам не придется вручную настраивать длину массива.
Следует отметить один важный момент: строки в стиле C подчиняются всем тем же правилам, что и массивы. Это означает, что вы можете инициализировать строку при создании, но после этого вы не можете присваивать ей значения с помощью оператора присваивания!
char myString [] {«строка»}; // нормально myString = «rope»; // не нормально! |
Поскольку строки в стиле C являются массивами, вы можете использовать оператор [] для изменения отдельных символов в строке:
#include int main () { char myString [] {«строка»}; myString [1] = ‘р’; std :: cout << myString << '\ n'; возврат 0; } |
Эта программа напечатает:
весна
При печати строки в стиле C std :: cout печатает символы, пока не встретит нулевой терминатор.Если вы случайно перезапишете нулевой терминатор в строке (например, присвоив что-то myString [6]), вы не только получите все символы в строке, но std :: cout будет просто печатать все в соседних слотах памяти до тех пор, пока это случается, когда попадает 0!
Обратите внимание, что это нормально, если массив больше, чем содержащаяся в нем строка:
#include int main () { имя символа [20] {«Alex»}; // использовать только 5 символов (4 буквы + нулевой терминатор) std :: cout << "Меня зовут:" << name << '\ n'; возврат 0; } |
В этом случае будет напечатана строка «Alex», а std :: cout остановится на нулевом ограничителе.Остальные символы в массиве игнорируются.
Струны и std в стиле C :: cin
Во многих случаях мы не знаем заранее, какой длины будет наша строка. Например, рассмотрим задачу написания программы, в которой нам нужно попросить пользователя ввести свое имя. Как долго их зовут? Мы не узнаем, пока они не войдут!
В этом случае мы можем объявить массив больше, чем нам нужно:
#include int main () { имя символа [255]; // объявляем массив достаточно большим, чтобы вместить 255 символов std :: cout << "Введите свое имя:"; std :: cin >> name; std :: cout << "Вы ввели:" << name << '\ n'; возврат 0; } |
В приведенной выше программе мы выделили массив из 255 символов для имени, предполагая, что пользователь не будет вводить такое количество символов.Хотя это обычно наблюдается в программировании на C / C ++, это плохая практика программирования, поскольку ничто не мешает пользователю ввести более 255 символов (непреднамеренно или злонамеренно).
Рекомендуемый способ чтения строк в стиле C с использованием std :: cin
выглядит следующим образом:
#include #include int main () { имя символа [255]; // объявляем массив достаточно большим, чтобы вместить 255 символов std :: cout << "Введите свое имя:"; std :: cin.getline (имя, std :: size (имя)); std :: cout << "Вы ввели:" << name << '\ n'; возврат 0; } |
Этот вызов cin.getline () считывает имя длиной до 254 символов (оставляя место для нулевого терминатора!). Любые лишние символы будут отброшены. Таким образом мы гарантируем, что не переполним массив!
Управление строками в стиле C
C ++ предоставляет множество функций для управления строками в стиле C как часть заголовка
strcpy () позволяет копировать строку в другую строку. Чаще всего это используется для присвоения значения строке:
#include int main () { char source [] {«Скопируйте это!» }; знаков [50]; std :: strcpy (назначение, исходный код); std :: cout << dest << '\ n'; // выводит "Скопируйте это!" возврат 0; } |
Однако strcpy () может легко вызвать переполнение массива, если вы не будете осторожны! В следующей программе dest недостаточно велик, чтобы вместить всю строку, поэтому возникает переполнение массива.
#include int main () { char source [] {«Скопируйте это!» }; символ [5]; // обратите внимание, что длина dest всего 5 символов! std :: strcpy (назначение, исходный код); // переполнение! std :: cout << dest << '\ n'; возврат 0; } |
Многие программисты рекомендуют вместо этого использовать strncpy (), которая позволяет указать размер буфера и гарантирует, что переполнение не произойдет.К сожалению, strncpy () не гарантирует, что строки завершаются нулем, что по-прежнему оставляет много места для переполнения массива.
В C ++ 11 предпочтительна strcpy_s (), которая добавляет новый параметр для определения размера места назначения. Однако не все компиляторы поддерживают эту функцию, и для ее использования необходимо определить __STDC_WANT_LIB_EXT1__ с целочисленным значением 1.
#define __STDC_WANT_LIB_EXT1__ 1 #include int main () { char source [] {«Скопируйте это!» }; символ [5]; // обратите внимание, что длина dest всего 5 символов! strcpy_s (dest, 5, source); // Ошибка выполнения произойдет в режиме отладки std :: cout << dest << '\ n'; возврат 0; } |
Поскольку не все компиляторы поддерживают strcpy_s (), strlcpy () является популярной альтернативой, даже несмотря на то, что она нестандартна и поэтому не включена во многие компиляторы.Здесь также есть свой набор проблем. Короче говоря, здесь нет универсального решения, если вам нужно скопировать строку в стиле C.
Еще одна полезная функция — функция strlen (), которая возвращает длину строки в стиле C (без нулевого терминатора).
#include #include #include int main () { имя символа [20] {«Alex» }; // использовать только 5 символов (4 буквы + нулевой терминатор) std :: cout << "Меня зовут:" << name << '\ n'; std :: cout << name << "содержит" << std :: strlen (name) << "букв.\ n "; std :: cout << name <<" имеет "<< std :: size (name) <<" символов в массиве. \ n "; // используйте sizeof (name) / sizeof (name [0]) если не поддерживает C ++ 17 return 0; } |
В приведенном выше примере печатается:
Меня зовут Алекс У Алекса 4 буквы. У Алекса 20 символов в массиве.
Обратите внимание на разницу между strlen () и std :: size (). strlen () печатает количество символов перед нулевым ограничителем, тогда как std :: size (или трюк sizeof ()) возвращает размер всего массива, независимо от того, что в нем находится.
Другие полезные функции:
strcat () — добавляет одну строку к другой (опасно)
strncat () — добавляет одну строку к другой (с проверкой длины буфера)
strcmp () — сравнивает две строки (возвращает 0, если равно )
strncmp () — Сравнить две строки до определенного количества символов (возвращает 0, если равно)
Вот пример программы, использующей некоторые из концепций этого урока:
1 2 3 4 5 6 7 8 9 10 11 12 13 140002 14 18 19 20 21 22 23 24 25 | #include #include #include int main () { // Попросите пользователя ввести строку символьный буфер [255]; std :: cout << "Введите строку:"; std :: cin.getline (буфер, std :: size (буфер)); int пробелов найдено {0}; int bufferLength {static_cast // Перебираем все символы, введенные пользователем для (int index {0}; index { // Если текущий символ — пробел, подсчитайте его если (буфер [индекс] == ») ++ пробелов найдено; } std :: cout << "Вы ввели" << spaceFound << "пробелы! \ N"; возврат 0; } |
Обратите внимание, что мы помещаем strlen (buffer)
вне цикла, так что длина строки вычисляется только один раз, а не каждый раз, когда проверяется условие цикла.
Не используйте строки в стиле C
Важно знать строки в стиле C, потому что они используются во многих кодах. Однако теперь, когда мы объяснили, как они работают, мы порекомендуем вам вообще избегать их, когда это возможно! Если у вас нет конкретной веской причины использовать строки в стиле C, используйте вместо них std :: string (определенную в заголовке std :: string_view
, которая будет рассмотрена в следующем уроке.
Используйте std :: string
или std :: string_view
(следующий урок) вместо строк в стиле C.
.
c # — что означает $ перед строкой?
Переполнение стека
- Около
Продукты
- Для команд
Переполнение стека
Общественные вопросы и ответыПереполнение стека для команд
Где разработчики и технологи делятся частными знаниями с коллегамиВакансии
Программирование и связанные с ним технические возможности карьерного ростаТалант
Нанимайте технических специалистов и создавайте свой бренд работодателяРеклама
Обратитесь к разработчикам и технологам со всего мира- О компании
.