как узнать сколько символов в string c
Урок №202. Длина и ёмкость std::string
Обновл. 17 Ноя 2020 |
При создании строки не помешало бы указать её длину и ёмкость (или хотя бы знать эти параметры).
Длина std::string
Длина строки — это количество символов, которые она содержит. Есть две идентичные функции для определения длины строки:
size_type string::length() const
size_type string::size() const
Обе эти функции возвращают текущее количество символов, которые содержит строка, исключая нуль-терминатор. Например:
Хотя также можно использовать функцию length() для определения того, содержит ли строка какие-либо символы или нет, эффективнее использовать функцию empty():
Есть еще одна функция, связанная с длиной строки, которую вы, вероятно, никогда не будете использовать, но мы все равно её рассмотрим:
size_type string::max_size() const — эта функция возвращает максимальное количество символов, которое может хранить строка. Это значение может варьироваться в зависимости от операционной системы и архитектуры операционной системы.
Ёмкость std::string
Ёмкость строки — это максимальный объем памяти, выделенный строке для хранения содержимого. Это значение измеряется в символах строки, исключая нуль-терминатор. Например, строка с ёмкостью 8 может содержать 8 символов.
size_type string::capacity() const — эта функция возвращает количество символов, которое может хранить строка без дополнительного перераспределения/перевыделения памяти.
Length: 10
Capacity: 15
Примечание: Запускать эту и следующие программы следует в полноценных IDE, а не в веб-компиляторах.
Обратите внимание, ёмкость строки больше её длины! Хотя длина нашей строки равна 10, памяти для неё выделено аж на 15 символов! Почему так?
Здесь важно понимать, что, если пользователь захочет поместить в строку больше символов, чем она может вместить, строка будет перераспределена и, соответственно, ёмкость будет больше. Например, если строка имеет длину и ёмкость равную 10, то добавление новых символов в строку приведет к её перераспределению. Делая ёмкость строки больше её длины, мы предоставляем пользователю некоторое буферное пространство для расширения строки (добавление новых символов).
Но в перераспределении есть также несколько нюансов:
Во-первых, это сравнительно ресурсозатратно. Сначала должна быть выделена новая память. Затем каждый символ строки копируется в новую память. Если строка большая, то тратится много времени. Наконец, старая память должна быть удалена/освобождена. Если вы делаете много перераспределений, то этот процесс может значительно снизить производительность вашей программы.
Во-вторых, всякий раз, когда строка перераспределяется, её содержимое получает новый адрес памяти. Это означает, что все текущие ссылки, указатели и итераторы строки становятся недействительными!
Обратите внимание, не всегда строки создаются с ёмкостью, превышающей её длину. Рассмотрим следующую программу:
Строки в языке C++ (класс string)
В языке C++ для удобной работы со строками есть класс string, для использования которого необходимо подключить заголовочный файл string.
Строки можно объявлять и одновременно присваивать им значения:
string S1, S2 = «Hello»;
Строка S1 будет пустой, строка S2 будет состоять из 5 символов.
Строки в языке C++ могут
Конструкторы строк
Конструкторы можно вызывать явно, например, так:
Неявно конструктор вызывается при объявлении строки с указанием дополнительных параметров. Например, так:
Подробней о конструкторах для строк читайте здесь.
Ввод-вывод строк
Строка выводится точно так же, как и числовые значения:
cout >» для объекта cin:
Можно считывать строки до появления символа конца строки при помощи функции getline. Сам символ конца строки считывается из входного потока, но к строке не добавляется:
Арифметические операторы
Подробней о методе resize.
clear
Подробней о методе clear.
empty
Подробней о методе empty.
push_back
Подробней о методе push_back.
append
Добавляет в конец строки несколько символов, другую строку или фрагмент другой строки. Имеет много способов вызова.
Подробней о методе append.
erase
Подробней о методе erase.
insert
Подробней о методе insert.
substr
Подробней о методе substr.
replace
Заменяет фрагмент строки на несколько равных символов, другую строку или фрагмент другой строки. Способы вызова аналогичны способам вызова метода append, только первыми двумя параметрами являются два числа: pos и count. Из данной строки удаляется count символов, начиная с символа pos, и на их место вставляются новые символы.
Подробней о методе replace.
Подробней о методе find.
rfind
Ищет последнее вхождение подстроки («правый» поиск). Способы вызова аналогичны способам вызова метода find.
Подробней о методе rfind.
find_first_of
Ищет в данной строке первое появление любого из символов данной строки str. Возвращается номер этого символа или значение string::npos.
find_last_of
Ищет в данной строке последнее появление любого из символов данной строки str. Способы вызова и возвращаемое значение аналогичны методу find_first_of.
Подробней о методе find_last_of.
find_first_not_of
Ищет в данной строке первое появление символа, отличного от символов строки str. Способы вызова и возвращаемое значение аналогичны методу find_first_of.
find_last_not_of
Ищет в данной строке последнее появление символа, отличного от символов строки str. Способы вызова и возвращаемое значение аналогичны методу find_first_of.
c_str
Возвращает указать на область памяти, в которой хранятся символы строки, возвращает значение типа char*. Возвращаемое значение можно рассматривать как C-строку и использовать в функциях, которые должны получать на вход C-строку.
Подсчет вхождений символов в строке в С++
ОТВЕТЫ
Ответ 1
Ответ 2
EDIT: код примера С++:
Также обратите внимание: я понимаю, что вы хотите что-то «как можно меньше», но я бы предложил вам использовать это решение. Как вы видите, вы можете использовать функцию для инкапсуляции кода для вас, поэтому вам не придется писать цикл for каждый раз, но можете просто использовать count_underscores(«my_string_») в остальной части вашего кода. Использование продвинутых алгоритмов на С++, конечно, возможно здесь, но я думаю, что это чрезмерно.
Ответ 3
Старомодное решение с правильно названными переменными. Это дает коду некоторый дух.
Ответ 4
Ответ 5
Вы называете это. Lambda version. )
Вам нужно несколько включений. Я оставляю вас в качестве упражнения.
Ответ 6
Как только вы узнаете, как найти следующего персонажа, заданного начальной позицией, вы постоянно продвигаете свой поиск (т.е. используете цикл), считая, когда идете.
Ответ 7
Вы можете узнать появление ‘_’ в исходной строке с помощью строковых функций. Функция find() принимает 2 аргумента, первая строка, чьи вхождения мы хотим найти, а второй аргумент принимает начальную позицию. Если цикл используется для поиска вхождения до конца строки источника.
Ответ 8
Подсчитать количество появлений символов в строке легко:
Ответ 9
Использование лямбда-функции для проверки того, что символ равен «_», будет увеличиваться только счетчик, в противном случае это недопустимый символ
Строки и массивы символов
Мы с вами уже познакомились с символами в уроке про типы данных. Напомню: символ является переменной (или константой) типа char и хранит в себе код буквы в таблице символов. Создан для удобства программиста, чтобы он мог работать не кодами, а с читаемыми символами. Как и в жизни, символы соединяются в слова, здесь они называются строки. У нас есть два набора инструментов по работе с ними: обычные строки (массивы символов) и String-строки.
String-строки
Давайте рассмотрим большой пример, из которого будет понятно, как объявить строку и как с ней работать, а также учтены некоторые тонкости:
Инструменты для String
Помимо набора методов, библиотека String имеет несколько перегруженных операторов, благодаря которым мы можем:
Во всех перечисленных случаях можно считать, что данные “сами превратятся в String” и будут взаимодействовать со String-строкой, стоящей слева от оператора. Это не совсем так, но для понимания достаточно. Итак, методы для работы со строками. Как и все методы, они применяются к своим объектам (к строкам) через точку. В рассмотренных ниже примерах строка называется myString.
Длина строки
Небольшой комментарий по поводу длины строки: в отличие от char array, узнать длину String строки можно только при помощи метода length() (потому что String-строка является динамическим массивом, а sizeof() выполняется на этапе компиляции):
Меры предосторожности
Строка по сути является динамическим массивом, её размер может меняться по ходу программы. Это очень удобно, но и очень опасно, потому что память может фрагментироваться, закончиться и т.д. Рассмотрим несколько базовых принципов безопасной работы со строками:
Массивы символов
Массивы символов, они же “char array”, являются ещё одним способом работы с текстовыми данными. Этот вариант имеет гораздо меньше возможностей по работе с текстом, но зато занимает меньше места в памяти (не используется библиотека String ) и работает значительно быстрее. К массиву символов применяются те же правила, какие работают для обычных массивов. Рассмотрим пример, в котором объявим массивы символов разными способами:
Можно работать с элементами строк как с массивами:
В отличие от строк, массивы символов нельзя:
Для этого существуют специальные функции, о которых мы поговорим ниже.
Длина строки char array
Здесь оператор sizeof() вернул количество байт, занимаемое массивом. Массив я специально объявил с размером бОльшим, чем содержащийся в нём текст. А вот оператор strlen() посчитал и вернул количество символов, которые идут с начала массива и до нулевого символа в конце текста (без его учёта). А вот такой будет результат при инициализации без указания размера массива:
Массив строк
Очень мощной фишкой массивов символов является возможность создать один массив с несколькими строками, и обращаться к ним по номеру. Выглядит это следующим образом:
Данный способ работы со строками хорош тем, что строки хранятся под номерами, и это крайне удобно при работе с дисплеями и в частности создании текстового меню: практически все библиотеки дисплеев умеют выводить массив символов одной командой.
F() macro
Строки (массивы символов) являются очень тяжёлым грузом, ведь текст в строке хранится в оперативной памяти микроконтроллера, а её не так уж и много. Есть готовый инструмент, позволяющий удобно хранить текстовые данные во Flash памяти микроконтроллера. Этот способ хорош для вывода фиксированных текстовых данных, например, в монитор порта или на дисплей:
Строка “Hello, World!” будет записана во Flash память и не займёт 14 байт (13 + нулевой) в оперативной.
Экономия памяти
“Строки” в массиве строк тоже хранятся в оперативной памяти, а рассмотренный выше F() macro к ним нельзя. То есть вот такой код приведёт к ошибке:
Как же быть? Массив строк можно сохранить в PROGMEM, программной памяти микроконтроллера, Flash. Вот такую конструкцию можно использовать как шаблон:
Да, сложно и громоздко, но при большом объёме текстовых данных это может спасти проект! Например при создании устройства с текстовым меню на дисплее. Более подробно о хранении строк в PROGMEM читайте в уроке про PROGMEM.
Инструменты для char array
Есть готовые функции, позволяющие конвертировать различные типы данных в строки:
* Примечание: base – основание системы исчисления, тут всё как при выводе в Serial:
И наоборот, можно преобразовывать строки в численные данные (функция вернёт результат):
2 кБ Flash памяти!! Максимально избегайте их применения в крупном проекте. Для преобразования можно сделать свою функцию, практически готовые варианты для всех типов данных можно найти в стандартной ардуиновской Print.cpp (ссылка на файл на гитхабе Arduino).
Подсчет количества символов в статье
Один из примеров подсчета количества символов в тексте (статьях) контентных проектов с использованием Google Analytics и Google Tag Manager для моего блога.
Статья носит исключительно образовательный характер, хорошо иллюстрирует возможности работы в GTM и Analytics, а также позволяет познакомиться сразу с несколькими важными темами – CSS-селекторами, объектами, свойства и функциями в JavaScript, использованием переменных GTM внутри других переменных, логическими типами, нестандартным триггером активации, пользовательским параметром и специальным отчетом в Google Analytics.
Специальный отчет Analytics с пользовательским параметром
Реализовывать буду следующим образом (это один из вариантов, и далеко не самой оптимальный!). Создам:
Переменная для получения содержимого статьи
Создаю переменную типа Элемент DOM с селектором .simple-text
Переменная типа Элемент DOM
Использование расширения CSS Selector Tester
Используя расширение CSS Selector Tester я подтвердил свое предположение, что текст статьи находится именно в этом классе. О том, что такое CSS-селекторы, читайте в этой статье. В переменной типа Элемент DOM можно использовать и идентификатор, если такой атрибут есть у отслеживаемого элемента. Сохраняю переменную.
Переменная типа «Константа»
Переменная типа Константа
Переменная подсчета количества символов статьи
Это переменная типа Собственный код JavaScript, которая имеет вид:
В GTM она выглядит так:
Переменная типа Собственный код JavaScript
Разберем этот код подробнее.
var articleString = <<Текст статьи>>.length – объявление переменной articleString, в которой будет хранится информация о количестве символов нашей статьи. Свойство length представляет длину строки. Для пустых строк будет возвращено 0, но таких у нас нет.
Подробнее о свойстве length читайте в этой статье.
Это же действие можно было бы сделать и без создания отдельной переменной <<Текст статьи>> в GTM, а просто добавив в код такую конструкцию:
var articleString = document.querySelectorAll(«.simple-text»)[0].textContent.length;
Отличие от innerText
element.innerText был введен Internet Explorer-ом. Работает по тому же принципу за небольшими исключениями: