Help people — C++ помогите со строками


Строки и структуры в C++. Уроки программирования

Строки в C++

Строка — последовательность (массив) символов. Если в выражении встречается одиночный символ, он должен быть заключен в одинарные кавычки. При использовании в выражениях строка заключается в двойные кавычки. Признаком конца строки является нулевой символ \0. В C++ строки можно описать с помощью массива символов (массив элементов типа char), в котором следует предусмотреть место для хранения признака конца строки.

Например, описание строки из 25 символов должно выглядеть так:

Здесь элемент s[24] предназначен для хранения символа конца строки.

Можно описать и массив строк:

Определен массив из 3 строк по 25 байт в каждой.

Для работы с указателями можно использовать (char *). Адрес первого символа будет начальным значением указателя.

Рассмотрим пример объявления и вывода строк.

Результат работы программы:

Но следует отметить, что если пользователь введет в одну переменную слова разделенные пробелом, то программа будет работать иначе:

Все дело в том, что функция cin вводит строки до встретившегося пробела. Более универсальной функцией является getline.

cin.getline(char *s, int n);

Функция предназначена для ввода с клавиатуры строки s с пробелами, в строке не должно быть более n символов. Следовательно, для корректного ввода строк, содержащих пробел, необходимо в нашей программе заменить cin>>s на cin.getline(s, 80).

Операции над строками

Строку можно обрабатывать как массив символов, используя алгоритмы обработки массивов или с помощью специальных функций обработки строк, некоторые из которых приведены ниже. Для работы с этими строками необходимо подключить библиотеку cstring.

Для преобразования числа в строку можно воспользоваться функцией sprintf из библиотеки stdio.h.

Некоторые функции работы со строками:

Прототип функции Описание функции
size_t strlen(const char *s) вычисляет длину строки s в байтах.
char *strcat(char *dest, const char *scr) присоединяет строку src в конец строки dest, полученная срока возвращается в качестве результата
char *strcpy(char *dest, const char *scr) копирует строку scr в место памяти, на которое указывает dest
char strncat(char *dest, const char *dest, size_t maxlen) присоединяет строку maxlen символов строки src в конец строки dest
char *strncpy(char *dest, const char *scr, size_t maxlen) копирует maxlen символов строки src в место памяти, на которое указывает dest
int ctrcmp(const char *s1, const char *s2) сравнивает две строки в лексикографическом порядке с учетом различия прописных и строчных букв, функция возвращает 0, если строки совпадают, возвращает — 1, если s1 располагается в упорядоченном по алфавиту порядке раньше, чем s2, и 1 — в противоположном случае.
int strncmp(const char *s1, const char *s2, size_t maxlen) сравнивает maxlen символов двух строк в лексикографическом порядке, функция возвращает 0, если строки совпадают, возвращает — 1, если s1 располагается в упорядоченном по алфавиту порядке раньше, чем s2, и 1 — в противоположном случае.
double atof(const char *s) преобразует строку в вещественное число, в случае неудачного преобразования возвращается число 0
long atol(const char *s) преобразует строку в длинное целое число, в случае неудачного преобразования возвращается 0
char *strchr(const char *s, int c); возвращает указатель на первое вхождение символа c в строку, на которую указывает s. Если символ c не найден, возвращается NULL
char *strupr(char *s) преобразует символы строки, на которую указывает s, в символы верхнего регистра, после чего возвращает ее

Тип данных string

Кроме работы со строками, как с массивом символов, в C++ существует специальный тип данных string. Для ввода переменных этого типа можно использовать cin, или специальную функцию getline.

getline(cin, s);

Здесь s — имя вводимой переменной типа string.

При описании переменной этого типа можно сразу присвоить значение этой переменной.

string var(s);

Здесь var — имя переменной, s — строковая константа. В результате этого оператора создается переменная var типа string, и в нее записывается значение строковой константы s. Например,

string v(«Hello»);

Создается строка v, в которую записывается значение Hello.

Доступ к i-му элементу строки s типа string осуществляется стандартным образом s[i]. Над строками типа string определенны следующие операции:

  • присваивания, например s1=s2;
  • объединения строк (s1+=s2 или s1=s1+s2) — добавляет к строке s1 строку s2, результат храниться в строке s1, пример объединения строк:
  • сравнения строк на основе лексикографического порядка: s1=s2, s1!=s2, s1 s2, s1 =s2 — результатом будет логическое значение;

При обработке строк типа string можно использовать следующие функции:

  • s.substr(pos, length) — возвращает подстроку из строки s, начиная с номера pos длинной length символов;
  • s.empty() — возвращает значение true, если строка s пуста, false — в противном случае;
  • s.insert(pos, s1) — вставляет строку s1 в строку s, начиная с позиции pos;
  • s.remove(pos, length) — удаляет из строки s подстроку length длинной pos символов;
  • s.find(s1, pos) — возвращает номер первого вхождения строки s1 в строку s, поиск начинается с номера pos, параметр pos может отсутствовать , в этом случае поиск идет с начала строки;
  • s.findfirst(s1, pos) — возвращает номер первого вхождения любого символа из строки s1 в строку s, поиск начинается с номера pos, который может отсутствовать.

Русский язык для строк

Думаю вы уже заметили, что при выводе русских букв, в консоли появляются «левые» символы. Для того чтобы избежать этого недоразумения, необходимо воспользоваться сторонней функцией CharToOemA. Подключаем библиотеку windows.h, она нужна для того, чтобы наша функция могла преобразовать строки в другую кодировку. Также, нам понадобиться дополнительный символьный массив. Исходный код программы будет выглядеть вот так:

Способ только что описанный достаточно не удобен. Но существует более простой вариант решения «русской» проблемы. Как видите, в программе используется функция setlocale(), вместо этого удобнее вписать в главную функцию следующую конструкцию:

Теперь у нас появляется библиотека windows.h, а также две новые функции: SetConsoleCP() и SetConsoleOutputCP().

Структуры в C++

Кроме числовых и символьных данных в C++ есть тип, который позволяет объединить разнородные данные и обрабатывать их как единое целое. Этот тип называется структурой. Структура является собранием одного или более объектов (переменных, массивов, указателей и т.д.), которые для удобства работы с ними объединены под одним именем.

Определение структуры состоит из двух шагов:

  • объявление структуры (задание нового типа данных, определенного пользователем); структура состоит из полей, например:
  • определение переменных типа «структура»:

Для обращения к полям структуры нужно указать имя переменной и через точку имя поля

Structura.pole

При работе с динамическими массивами структур к их полям можно обращаться и по-другому. Обращение к полю year i-го элемента динамического массива структуры x можно записать так:

Строки в языке C++ (класс string)

В языке C++ для удобной работы со строками есть класс string, для использования которого необходимо подключить заголовочный файл string.

Строки можно объявлять и одновременно присваивать им значения:

string S1, S2 = «Hello»;

Строка 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’ .

Неявно конструктор вызывается при объявлении строки с указанием дополнительных параметров. Например, так:

Подробней о конструкторах для строк читайте здесь.


Ввод-вывод строк

Строка выводится точно так же, как и числовые значения:

cout >» для объекта cin:

В этом случае считывается строка из непробельных символов, пропуская пробелы и концы строк. Это удобно для того, чтобы разбивать текст на слова, или чтобы читать данные до конца файла при помощи while (cin >> S) .

Можно считывать строки до появления символа конца строки при помощи функции getline. Сам символ конца строки считывается из входного потока, но к строке не добавляется:

Арифметические операторы

Со строками можно выполнять следующие арифметические операции:
= — присваивание значения.
+= — добавление в конец строки другой строки или символа.
+ — конкатенация двух строк, конкатенация строки и символа.
== , != — посимвольное сравнение.
, > , , >= — лексикографическое сравнение.

То есть можно скопировать содержимое одной строки в другую при помощи операции S1 = S2, сравнить две строки на равенство при помощи S1 == S2, сравнить строки в лексикографическом порядке при помощи S1 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 и более сдвигаются вправо.

Цукерберг рекомендует:  Тест по PHP. Работа с строками

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.

Ищет в данной строке первое вхождение другой строки 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_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-строку.

BestProg


Работа со строками. Класс string . Конструкторы класса. Функции assign() , append() , insert() , replace() , erase() , find() , rfind() , compare() , c_str() . Примеры

Содержание

1. Какое назначение класса string в программах на C++?

Класс string предназначен для работы со строками типа char* , которые представляют собой строку с завершающим нулем. Класс string был введенн как альтернативный вариант для работы со строками типа char* . Строки, которые завершаются символом ‘\0’ еще называются C-строками. Поскольку, string есть классом, то можно объявлять объекты этого класса.

2. Какие модули (библиотеки) нужно подключить, чтобы использовать возможности класса string в MS Visual Studio C++?

Чтобы использовать возможности класса string в MS Visual Studio (C++), нужно подключить библиотеку и пространство имен std .

3. Каким образом осуществляется объявление переменной типа string ? Примеры

Объявление переменной типа string осуществляется точно так же как и обычной переменной. Возможный вариант объявления с одновременной инициализацией.

4. Какие преимущества и недостатки дает использование класса string в сравнении с типом char* ?

Создание нового типа string было обусловлено недостатками работы с строками символов, который демонстрировал тип char* . В сравнении с типом char* тип string имеет следующие основные преимущества:

  • возможность обработки строк стандартными операторами C++ ( = , + , = = , <> и т.п.). Как известно, при использовании типа char* даже наиболее простые операции со строками выглядели сложно и требовали написания чрезмерного программного кода;
  • обеспечение лучшей надежности (безопасности) программного кода. Например, при копировании строк, тип string обеспечивает соответствующие действия, которые могут возникнуть в случае, если строка-источник имеет больший размер чем строка-приемник;
  • обеспечение строки, как самостоятельного типа данных. Объявление типа string как строки есть единым для всех переменных в программе, которая обеспечивает непротиворечивость данных.

Основным недостатком типа string в сравнении с типом char* , есть замедленная скорость обработки данных. Это связано с тем, что тип string – это, фактически, контейнерный класс. А работа с классом требует дополнительной реализации программного кода, который, в свою очередь занимает лишнее время.

5. Какие операторы можно использовать с объектами класса string ?

Класс string есть удобен тем, что позволяет удобно манипулировать строками, используя стандартные (перегруженные) операторы.

С объектами класса string можно использовать нижеследующие операторы

  • = – присваивание
  • + – конкатенация (объединение строк)
  • += – присваивание с конкатенацией
  • == – равенство
  • != – неравенство
  • – меньше
  • – меньше или равно
  • > – больше
  • >= – больше или равно
  • [ ] – индексация

Пример, который демонстрирует использование вышеприведенных операторов

6. Содержит ли класс string конструкторы?

Как и любой класс, класс string имеет ряд конструкторов. Основные из них следующие:

7. Примеры инициализации с помощью конструкторов

Ниже приведены примеры инициализации переменных типа string

8. Присваивание строк. Функция assign() . Примеры

Чтобы присвоить одну строку другой, можно применить один из двух методов:

  • использовать оператор присваивания ‘=’ ;
  • использовать функцию assign() из класса string .

Функция assign() имеет несколько перегруженных реализаций.

Первый вариант – это вызов функции без параметров

В этом случае происходит простое присваивание одной строки другой.

Второй вариант позволяет копировать заданное количество символов из строки:

  • s – объект, из которого берется исходная строка;
  • st – индекс (позиция) в строке, из которой начинается копирование num символов;
  • num – количество символов, которые нужно скопировать из позиции st ;
  • size_type – порядковый тип данных.

Третий вариант функции assign() копирует в вызывающий объект первые num символов строки s :

  • s – строка, которая завершается символом ‘\0’ ;
  • num – количество символов, которые копируются в вызывающий объект. Копируются первые num символов из строки s .

Ниже приведен пример с разными реализациями функции assign() .

Пример.

9. Объединение строк. Функция append() . Пример

Для объединения строк используется функция append() . Для добавления строк также можно использовать операцию ‘+’ , например:

Однако, функция append() хорошо подходит, если нужно добавлять часть строки.

Функция имеет следующие варианты реализации:

В первом варианте реализации функция получает ссылку на строчный объект s , который добавляется к вызывающему объекту. Во втором варианте реализации функция получает указатель на строку типа const char * , которая завершается символом ‘\0’ .

Пример. Демонстрация работы функции append() .

10. Вставка символов в строке. Функция insert() . Пример

Чтобы вставить одну строку в заданную позицию другой строки нужно использовать функцию insert() , которая имеет несколько вариантов реализации.

Первый вариант функции позволяет вставить полностью всю строку s в заданную позицию start вызывающей строки (вызывающего объекта):

Второй вариант функции позволяет вставить часть (параметры insStart , num ) строки s в заданную позицию start вызывающей строки:

В вышеприведенных функциях:

  • s – строка, которая вставляется в вызывающую строку;
  • start – позиция в вызывающей строке, из которой осуществляется вставка строки s ;
  • insStart – позиция в строке s , из которой происходит вставка;
  • num – количество символов в строке s , которые вставляются с позиции insStart .
11. Замена символов в строке. Функция replace() . Пример

Функция replace() выполняет замену символов в вызывающей строке. Функция имеет следующие варианты реализации:

В первом варианте реализации вызывающая строка заменяется строкой s . Есть возможность задать позицию ( start ) и количество символов ( num ) в вызывающей строке, которые нужно заменить строкой s .

Второй вариант функции replace() отличается от первого тем, что позволяет заменять вызывающую строку только частью строки s . В этом случае задаются два дополнительных параметра: позиция replStart и количество символов в строке s , которые образуют подстроку, которая заменяет вызывающую строку.

Пример. Демонстрация работы функции replace() .

12. Удаление заданного количества символов из строки. Функция erase() . Пример

Для удаления символов из вызывающей строки используется функция erase() :

  • index – индекс (позиция), начиная из которой нужно удалить символы в вызывающей строке;
  • num – количество символов, которые удаляются.

Пример.

13. Поиск символа в строке. Функции find() и rfind() . Примеры

В классе string поиск строки в подстроке можно делать двумя способами, которые отличаются направлением поиска:

  • путем просмотра строки от начала до конца с помощью функции find() ;
  • путем просмотра строки от конца к началу функцией rfind() .

Прототип функции find() имеет вид:


  • s – подстрока, которая ищется в строке, что вызывает данную функцию. Функция осуществляет поиск первого вхождения строки s . Если подстрока s найдена в строке, что вызвала данную функцию, тогда возвращается позиция первого вхождения. В противном случае возвращается -1;
  • start – позиция, из которой осуществляется поиск.

Прототип функции rfind() имеет вид:

  • s – подстрока, которая ищется в вызывающей строке. Поиск подстроки в строке осуществляется от конца к началу. Если подстрока s найдена в вызывающей строке, то функция возвращает позицию первого вхождения. В противном случае функция возвращает -1;
  • npos – позиция последнего символа вызывающей строки;
  • start – позиция, из которой осуществляется поиск.

Пример 1. Фрагмент кода, который демонстрирует результат работы функции find()

Пример 2. Демонстрация работы функции rfind() .

14. Сравнение частей строк. Функция compare() . Пример

Поскольку тип string есть классом, то, чтобы сравнить две строки между собой можно использовать операцию ‘= =’ . Если две строки одинаковы, то результат сравнения будет true . В противном случае, результат сравнения будет false .

Но если нужно сравнить часть одной строки с другой, то для этого предусмотрена функция compare() .

Прототип функции compare() :

  • s – строка, которая сравнивается с вызывающей строкой;
  • start – позиция (индекс) в строке s , из которой начинается просмотр символов строки для сравнения;
  • num – количество символов в строке s , которые сравниваются с вызывающей строкой.

Функция работает следующим образом. Если вызывающая строка меньше строки s , то функция возвращает -1 (отрицательное значение). Если вызывающая строка больше строки s , функция возвращает 1 (положительное значение). Если две строки равны, функция возвращает 0.

Пример. Демонстрация работы функции compare() :

15. Получение строки с символом конца строки ‘\0’ ( char * ). Функция c_str() . Пример

Чтобы получить строку, которая заканчивается символом ‘\0’ используется функция c_str() .

Функция объявлена с модификатором const . Это означает, что функция не может изменять вызывающий объект (строку).

Пример 1. Преобразование типа string в const char * .

Пример 2.

Ниже продемонстрирован перевод строки из string в тип System::String для отображения его в элементе управления типа Label для приложений типа Windows Forms Application .

16. Как определить длину строки типа string ? Функция length()

Для определения количества символов в строке используется функция length() без параметров.

Функции для работы со строками в C++

После того, как мы с вами познакомились со строками и символьными массивами в C++, рассмотрим самые распространённые функции для работы с ними. Урок будет полностью построен на практике. Мы будем писать собственные программы-аналоги для обработки строк и параллельно использовать стандартные функции библиотеки cstring ( string.h – в старых версиях). Так вы примерно будете себе представлять, как они устроены. К стандартным функциям библиотеки cstring относятся:

    • strlen() – подсчитывает длину строки (количество символов без учета \0);
    • strcpy() – копирует символы одной строки в другую;
  • strcmp() – сравнивает между собой две строки .

Это конечно не все функции, а только те, которые мы разберём в этой статье.

strlen() (от слова length – длина)

Наша программа, которая подсчитает количество символов в строке:

Для подсчёта символов в строке неопределённой длины (так как вводит её пользователь), мы применили цикл while – строки 13 – 17. Он перебирает все ячейки массива (все символы строки) поочередно, начиная с нулевой. Когда на каком-то шаге цикла встретится ячейка ourStr [amountOfSymbol] , которая хранит символ \0 , цикл приостановит перебор символов и увеличение счётчика amountOfSymbol .

Так будет выглядеть код, с заменой нашего участка кода на функцию strlen() :

Как видите, этот код короче. В нем не пришлось объявлять дополнительные переменные и использовать цикл. В выходном потоке cout мы передали в функцию строку – strlen(ourStr) . Она посчитала длину этой строки и вернула в программу число. Как и в предыдущем коде-аналоге, символ \0 не включен в общее количество символов.

Результат будет и в первой программе и во второй аналогичен:

strcat() (от слова concatenation – соединение)

Программа, которая в конец одной строки, дописывает вторую строку. Другими словами – объединяет две строки.

По комментариям в коде должно быть всё понятно. Ниже напишем программу для выполнения таких же действий, но с использованием strcat() . В эту функцию мы передадим два аргумента (две строки) – strcat ( someText1 , someText2 ) ; . Функция добавит строку someText2 к строке someText1 . При этом символ ‘\0’ в конце someText1 будет перезаписан первым символом someText2 . Так же она добавит завершающий ‘\0’

Реализация объединения двух строк, используя стандартную функцию, заняла одну строчку кода в программе – 14-я строка.

На что следует обратить внимание и первом и во втором коде – размер первого символьного массива должен быть достаточным для помещения символов второго массива. Если размер окажется недостаточным – может произойти аварийное завершение программы, так как запись строки выйдет за пределы памяти, которую занимает первый массив. Например:

В этом случае, строковая константа “Учите С++ c нами!” не может быть записана в массив someText1 . В нём недостаточно места, для такой операции.

Если вы используете одну из последних версий среды разработки Microsoft Visual Studio, возможно возникновение следующей ошибки: “error C4996: ‘strcat’: This function or variable may be unsafe. Cons >strcat – это strcat_s .

Она заботится о том, чтобы не произошло переполнение буфера (символьного массива, в который производится запись второй строки). Среда предлагает вам использовать новую функцию, вместо устаревшей. Почитать больше об этом можно на сайте msdn. Подобная ошибка может появиться, если вы будете применять функцию strcpy , о которой речь пойдет ниже.

strcpy() (от слова copy – копирование)

Реализуем копирование одной строки и её вставку на место другой строки.

Применим стандартную функцию библиотеки cstring:

Пробуйте компилировать и первую, и вторую программу. Увидите такой результат:

strcmp() (от слова compare – сравнение)

Эта функция устроена так: она сравнивает две Си-строки символ за символом. Если строки идентичны (и по символам и по их количеству) – функция возвращает в программу число 0. Если первая строка длиннее второй – возвращает в программу число 1, а если меньше, то -1. Число -1 возвращается и тогда, когда длина строк равна, но символы строк не совпадают.

Программа с strcmp() :

Делитесь в социальных сетях нашими статьями со своими знакомыми, которые так же изучают основы программирования на языке С++.

45 thoughts on “ Функции для работы со строками в C++ ”

while (true) // запускаем бесконечный цикл
<
someText1[count] = someText2[count]; // копируем посимвольно
if (someText2[count] == ‘\0’) // если нашли \0 у второй строки
<
break; // прерываем цикл
>
count++;
>
Мне не понятно куда делась остальная часть строки “Сaйт purecodecpp.com!” ,
если по идее должно получиться так: Основы С++pp.com.
Мы копируем посимвольно меньшую строку в большую, так почему остаток someText1 удаляется?

Потому, что мы копируем не меньшую в большую, а вторую в первую. И когда подойдет ‘\0’ во второй строке он тоже перезапишется в первый массив. Далее, когда будет считываться первый массив, то этот ноль и покажет конец строки и не важно, что там было за ним записано. Это будет конец строки.

#include
#include
using namespace std;

int main()
<
setlocale(LC_ALL, “rus”);

char string_Array_1[] = “Вася, ты что, устал?”;
char string_Array_2[] = “Вася, ты что, устал!”;

Интересный баг в этом коде.
Скопировал, сделал два одинаковых текста “Вася, ты что, устал!” в char string_Array_1[] и char string_Array_2[] и проверил:
1. Пока строки одинаковы то всё GOOD.
2. Если первую строку сделать длиннее то получаю ” -1 ” (инвертировано).
3. Если первую строку сделать короче то получаю ” 1 ” (инвертировано).
Дальше интереснее.
4. Если в первой строке в слове ” устал ” букву ” у ” поменять на ” т ” то получаю ” -1 ”
5. Если в первой строке в слове ” устал ” букву ” у ” поменять на ” ф ” то получаю ” 1 ”
6. Если во второй строке в слове ” устал ” букву ” у ” поменять на ” т ” то получаю ” 1 ”
7. Если во второй строке в слове ” устал ” букву ” у ” поменять на ” т ” то получаю ” -1 ”
Слово ” устал ” я взял для примера. Букву ” у ” я менял на предыдущую и следующую в алфавите. Это работает с любой заменой букв ( ” а ” и ” я ” я не смог поменять).

Это не баг (как я думал). Это связано с кодировкой ASCII. Саму кодировку ASCII можно загуглить. Вот и выходит что “у” по этой кодировке больше “т” и меньше “ф”


Получается, что ‘?’ длиннее чем ‘!’
Это так.

Чем больше код символа в таблице ASCII тем “длиннее”.
“B” длиннее “А”, а “D” длиннее “B”.
Знаков препинания это тоже касается.
У “!” код 33, а у “?” код 63, значит ? > !

Да, немного разобравшись я понял (догадался) что тут идёт привязка к кодировке ASCII

SBP-Program

Работа со строками в C

Работа со строками в C

Имеется ряд функций для работы со строками в C.

Файл String.h содержит прототипы функций работы со строками C.

Прямо сейчас на примерах рассмотрим Си функции работы со строками.

strcmp

Сравнение строк в C, пример:

Две C строки объявлены в примере. Они одинаковы. Предложим функции сравнения строк в C strcmp сравнить эти строки. Прототип функции strcmp в файле String.h:

Если символы строки _Str1 раньше встречаются в алфавите, то _Str1 больше, чем _Str2 и результат функции будет меньше нуля. Если они равны, как в примере, то результат равен нулю. Если символы строки _Str2 раньше встречаются в алфавите, то _Str2 больше, чем _Str1 и результат функции будет меньше нуля. Функция strcmp различает большие и маленькие буквы.

В примере строки равны, поэтому получаем:

Нулевой результат говорит о том, что строки равны.

stricmp

Ещё одна функция сравнения строк в Си в файле String.h

игнорирует разницу больших и маленьких букв, в остальном такая же как и strcm.

strlen

Длину строки в Си определяет функция strlen из файла String.h:

Функция strlen возвращает длину строки C в виде количества байтов. Пример strlen:

В примере строка “stroka” содержит 6 символов. Функция определения длины строки C strlen выдаёт результат 6 байтов, т.е. одному символу соответствует один байт. Так оно и есть на самом деле.

strcpy

strcpy – копирование строк в C. Это ещё одна функция работы со строками C. Пример копирования строки в Си:

В примере создаём массив cMassiv для элементов типа char, и строку szStr. Функция strcpy копирует szStr в первый элемент массива, т.е. в cMassiv[0].

Прототип функции strcpy:

strncpy

strncpy – копирование строк в C. Это ещё одна функция работы со строками C. Пример копирования строки в Си:

В примере создаём массив cMassiv для элементов типа char, и строку szStr. Функция strcpy копирует szStr в первый элемент массива, т.е. в cMassiv[0]. А далее с помощью функции strncpy копируем 3 первых символа строки szStr2 в строку, хранящуюся в первом элементе массива, т.е. в cMassiv[0].

Прототип функции strncpy:

strcat

strcat – конкатенация строк в C, т.е. присоединение одной строки к другой. Это ещё одна функция работы со строками C. Пример конкатенации строки в Си:

Прототип функции strcat:

strncat

strncat – конкатенация строк в C, т.е. присоединение одной строки к другой. Это ещё одна функция работы со строками C. Пример конкатенации строки в Си:

Здесь прибавляем три символа втрой строки к первой.

Прототип функции strncat:

strstr

strstr – поиск первого вхождения одной строки в другую. Это ещё одна функция работы со строками C. Пример в Си:

Help people — C++ помогите со строками

В современном стандарте C++ определен класс с функциями и свойствами (переменными) для организации работы со строками (в классическом языке C строк как таковых нет, есть лишь массивы символов char ):

Для работы со строками также нужно подключить стандартный namespace :

В противном случае придётся везде указывать описатель класса std::string вместо string .

Ниже приводится пример программы, работающей со string (в старых си-совместимых компиляторах не работает!):

Основные возможности, которыми обладает класс string :

  • инициализация массивом символов (строкой встроенного типа) или другим объектом типа string . Встроенный тип не обладает второй возможностью;
  • копирование одной строки в другую. Для встроенного типа приходится использовать функцию strcpy() ;
  • доступ к отдельным символам строки для чтения и записи. Во встроенном массиве для этого применяется операция взятия индекса или косвенная адресация с помощью указателя;
  • сравнение двух строк на равенство. Для встроенного типа используются функции семейства strcmp() ;
  • конкатенация (сцепление) двух строк, дающая результат либо как третью строку, либо вместо одной из исходных. Для встроенного типа применяется функция strcat() , однако чтобы получить результат в новой строке, необходимо последовательно задействовать функции strcpy() и strcat() , а также позаботиться о выделении памяти;
  • встроенные средства определения длины строки (функции-члены класса size() и l ength() ). Узнать длину строки встроенного типа можно только вычислением с помощью функции strlen() ;
  • возможность узнать, пуста ли строка.

Рассмотрим эти базовые возможности более подробно.

Инициализация строк при описании и длина строки (не включая завершающий нуль-терминатор):

Строка может быть задана и пустой:

Для проверки того, пуста ли строка, можно сравнить ее длину с 0:

или применить метод empty() , возвращающий true для пустой строки и false для непустой:

Третья форма создания строки инициализирует объект типа string другим объектом того же типа:

Строка st3 инициализируется строкой st . Как мы можем убедиться, что эти строки совпадают? Воспользуемся оператором сравнения ( == ):

Как скопировать одну строку в другую? С помощью обычной операции присваивания:

Для сцепления строк используется операция сложения ( + ) или операция сложения с присваиванием ( += ). Пусть даны две строки:

Мы можем получить третью строку, состоящую из конкатенации первых двух, таким образом:

Если же мы хотим добавить s2 в конец s1 , мы должны написать:

Операция сложения может сцеплять объекты класса string не только между собой, но и со строками встроенного типа. Можно переписать пример, приведенный выше, так, чтобы специальные символы и знаки препинания представлялись встроенным типом char * , а значимые слова – объектами класса string :

Подобные выражения работают потому, что компилятор «знает», как автоматически преобразовывать объекты встроенного типа в объекты класса string . Возможно и простое присваивание встроенной строки объекту string :

Обратное преобразование при этом не работает. Попытка выполнить следующую инициализацию строки встроенного типа вызовет ошибку компиляции:

Чтобы осуществить такое преобразование, необходимо явно вызвать функцию-член с названием c_str() («строка Си»):

Функция c_str() возвращает указатель на символьный массив, содержащий строку объекта string в том виде, в каком она находилась бы во встроенном строковом типе. Ключевое слово const здесь предотвращает «опасную» в современных визуальных средах возможность непосредственной модификации содержимого объекта через указатель.

К отдельным символам объекта типа string , как и встроенного типа, можно обращаться с помощью операции взятия индекса. Вот, например, фрагмент кода, заменяющего все точки символами подчеркивания:

Но лучше читать документацию по C++ и пользоваться его возможностями. Например, предыдущее действие мы могли бы выполнить вызовом одной-единственной функции replace() :

Правда, здесь использован не метод replace класса string , а одноимённый алгоритм:

Поскольку объект string ведет себя как контейнер, к нему могут применяться и другие алгоритмы. Это позволяет решать задачи, не решаемые напрямую функциями класса string .


Ниже приводится краткое описание основных операторов и функций класса string , ссылки в таблице ведут к русскоязычным описаниям в интернете. Более полный список возможностей класса string можно получить, например, в Википедии или на сайте cplusplus.com.

Задание символов в строке

присваивает значения строке

назначает символы строке

Доступ к отдельным символам

получение указанного символа с проверкой выхода индекса за границы

получение указанного символа

получение первого символа

получение последнего символа

возвращает указатель на первый символ строки

возвращает немодифицируемый массив символов С , содержащий символы строки

Проверка на вместимость строки

проверяет, является ли строка пустой

возвращает количество символов в строке

возвращает максимальное количество символов

Помогите разобраться со строками!

Код выполняется неправильно. Стал разбираться в чем проблема, отслеживал пошагво
в результате получается так:
после выполнения строчки (2), temp1=»» (вроде так и должно быть);
после выполнения(3) temp2=»eve_byte» (откуда этот текст взялся. )
после выполнения (6) temp2=»eve_byte\x1E» (а откуда взялись эти символы \x1E ?)
ну а дальше у же не так интересно, дальше эти непонятные символы все портят.

Пожалуйста, подскажите чего не так?

7 ответов

В этой строке оператор new выделяет память, но он ничем её не заполняет! В выделенном участке памяти может находиться что угодно.

Ничего удивительного — это мусор. Каждый раз может быть любое значение.

Хелп внимательно читаем (особенно примеры)
[quote=BCB Help]
AnsiString::c_str() returns a non const temporary pointer to the internal string buffer in the AnsiString object. The pointer is invalid once the statement in which it is used has finished executing. That is,don’t do something like this:

char* cp = Edit1->Text.c_str();
char* cp2 = strtok( cp, » \t\n» ); // cp may no longer be valid

If you need a persistent pointer, you MUST copy the string into its own buffer:

char* cp = new char[ Edit1->Text.Length() + 1 ];
strcpy( cp, Edit1->Text.c_str() );
[/quote]

мусор? а почему этот мусор имеет такой осмысленный вид и каждый раз этот мусор у меня один и тот же?
А почему в первой переменной temp1 этого мусора нету? и никогда не бывает?

Т.е. согласно этого хелпа конструкция

Строки

В C++ работа со строками осуществляется с помощью символьных массивов. Для этого строку представляют конечным набором символов, с которым можно работать при помощи массива типа char.

Простейший пример выглядит так

Создался нефиксированный массив символов, который получил 3 элемента. Вызвать можно любой из этих символов, указав его номер.

Существует множество функций для работы с таким представлением строк.

Для примера возьмем часть кода.

Первые две строки ушли на создание строк. Третья строка вычисляет длину s с помощью функции strlen. Функция strcpy выполняет копирование строки s2 в s, при этом идет полная замена предыдущих символов. Функции strcat не копирует, а объединяет строки, результат объединения сохраняется в первую строку, в данном случае в s.

Расширения для предыдущих функций strncpy и strncat добавляют параметр, указывающий с каким количеством символов из второй строки будет работать функция. Последняя strcmp сравнивает 2 строки, выводя 0, если они равны, и +1 или -1 если одна из строк больше. Строки рассматриваются посимвольно, и результат рассчитывается по числовому коду первых неодинаковых символов.

Следует отметить, что функции strcpy, strncpy, strcat, strncat не следят за выделением памяти, так что память нужно выделять с помощью других команд. В данном примере в самом начале для каждой строки зарезервировано место под хранение 100 символов.

Help people — C++ помогите со строками

Hey guys, this is an assignment, i don’t want it all done for me i just want some help to get on the right track. the one thing im struggling with is how to properly use the v_heap.h in mem_heap.h and mem_heap.cpp. If anyone could give me an example of some sort or just set me on the right track i would greatly appreciate it! I’ll post the information below (i am new and have missed a few lectures and labs due to personal reasons but once again any help would be greatly appreciated!):

. You MUST NOT use new , delete , malloc , calloc, or free in your program.

I am also interested in this as how would one allocate memory on the heap without any of the calls mentioned? WTF?

edit:
Maybie they mean not outside vheap class?
I am gonna try this in my compiler and see if i can help you.

Yea not outside of vheap.h it already uses new and delete in it to allocate and deallocate the memory

vheap = new char[HEAP_SIZE];

and in the deconstructor uses delete!

any help would be greatly appreciated!

@savavampir: You just don’t allocate memory. Period. The challenge is clear: You have HEAP_SIZE bytes available for EVERYTHING, including both the private data and the buffers you hand out.

What is not clear is how the functions should inform whenever the heap is out of memory. Throw std::bad_alloc?

Anyway, @OP: This type of assignment is not for a beginner. Your question is beginner-like. Something doesn’t fit here. You either missed a big fat lot of lectures or something else is going on.

I have only missed a few but there was one vital one that i missed that did something similar with virtual classes like vheap being used in memheap.h and memheap.cpp .

Been trying to get hold of my tutor for some advice just having some bad luck (holidays and various others!) i have been able to do the tutorials up to one thats similar to this.

Ok, so let me ask: Do you know how to create a derived class? If yes, then start there: Create a new class that inherits (or derives) from VHeap.

After that, do you know how to override virtual methods? If yes, then do that.

Do you know how to write constructors? If yes, write a constructor for your new class that conforms to the assignment’s specification (one that allows the user of the heap to specify the heap size).

Do you know how to declare structs? Declare one that helps you write vdelete(), vsizeof() and printHeapState().

And so on. If you get stuck at any particular point, then post a specific question.

I’am just interested in this task as i am beginner too.
I am stuck at this function implementation:

virtual void vdelete(void* mem) <>

A release method where the user can return previously allocated memory back to the heap.
When memory is released it should ensure that adjacent, available memory segments are
consolidated into a single available segment.

What to do here? How to approach this?
1. Does this mean that i need to delete/(zero(fied) field) requested segment and shift other elements to be defragmented?
2. Or to preserve somewhere allocated segments, delete whole block (vheap), new it again, insert preserved?
3. Some other method i am not informed about, when you can (partially) deallocate parts of pointer to an array?
I am not native english speaker so i might wrongly express my self.

edit: How to know at what offset is pointer in question?

You’ve inherited vheap so you can manipulate it in MemHeap class!

edit: I am not going to bed any time soon, so if someone can explain my troubles please?
Thanks for your time.

1. R/ You cannot shift memory that is in use. It will crash the program that uses the heap! That is the job of advanced heaps like .Net’s garbage collector. Not good for C++.
2. R/ You cannot delete/new! It will delete other allocated objects plus the assignment forbids it.
3. R/No. The thing is purely mathematical.

Say this is your heap: AAAAFFFFAAAAFFFF. That is: 4 bytes (A)llocated, then 4 bytes (F)ree, then 4 A, then another 4 F. Imagine you are requested to vdelete() the second block that is allocated. This means that your heap should know that now there is a SINGLE block of 12 bytes available, as opposed to reporting 3 blocks of 4 bytes each. In other words, the heap must consolidate the free block that precedes the deleted block with the deleted block and the free block that succeeded it.

Ввести и вывести строку с пробелами несколько раз

Нужно несколько раз ввести и вывести строку, которая содержит пробелы. Сколько раз ввести-вывести — это на усмотрение пользователя. Пытался так, но не работает.

Программа компилируется и цикл повторяется, но когда переменной i присваиваю значение 1 дальше строка не вводится. Выглядит это так:

И так пока я не выйду из цикла. Подскажите в чем ошибка и как исправить.

4 ответа 4

Дело в том, что все символы после числа и ‘\n’ вместе с ними после ввода 1 в

остаются во входном потоке.

Реально в Вашем случае там скорее всего будут символы \r\n.

непосредственно перед while(i==1); и все заработает.

Цукерберг рекомендует:  Отзывы о профессии Performance-маркетинг
Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих