Як скласти два рядки?
Необроблений виняток у "0x003fd2e9 (msvcr100d.dll)" у "test1.exe": 0xC0000005: Порушення прав доступу під час запису "0x00a47868".
2,907 8 8 золотих знаків 49 49 срібних знаків 95 95 бронзових знаків
А пам'ять хто виділятиме? Терміново курити рядки та розподіл пам'яті.
Чому тег стоїть c++?! У С++ оголошуємо рядки через стандартний клас std::string. У нього реалізований оператор +, так і додаємо. Для чистого C читайте man asprintf.
Так З чи З++? У С++ ні про яке char* slovo2 = "riger"; мови бути не може, але раптом використовується std::cout. Що то за каша?
5 відповідей 5
Проблема у рядку
strcat (slovo1, slovo2);
Функція strcat приєднує до рядка, переданого першим параметром, рядок, переданого другим параметром. У разі рядки - це масиви елементів типу char . У C++ масиви є динамічними структурами, тобто що неспроможні змінювати свій розмір під час виконання програми. Тому в масиві (рядку), переданому першим параметром в strcat , має бути достатньо місця, щоб туди помістилися обидва рядки. Оголошуючи рядок так
char* slovo1 = "proger";
ви створюєте масив char 'ів розміром рівно в довжину рядка "proger" (плюс один елемент під нуль-термінатор). Якщо ви хочете скласти два рядки, вам доведеться виділити пам'ять під результат:
cahr * word = new char [strlen (slovo1) + strlen (slovo2) + 1]; strcat(slovo, slovo1); strcat(slovo, slovo2); printf(slovo);
Є й інші методи. Наприклад, з використанням класу stringstream :
stringstream ss; ss
Або використовуючи клас string :
string slovo1 = "proger"; string slovo2 = "riger"; slovo1 = slovo1 + slovo2; cout
string в C++: рядки простими словами
У стандартній бібліотеці C++ std::string є ключовим класом для роботи з рядками.Цей клас надає розробникам зручний спосіб керування та маніпуляції рядками, замінюючи традиційні масиви символів. У цій статті ми розглянемо основні аспекти std::string та його можливості у C++.
Що таке рядки (string) у C++
string - це зручніша альтернатива рядками в стилі C, яку можна використовувати в C++. Внутрішній пристрій string схожий на вектор символів, ми можемо змінювати рядок та його розмір на льоту.
Давайте розглянемо простий приклад роботи з рядками C++:
#include
using
namespace std;
int
main()
string greeting =
"Привіт";
// ініціалізація рядка string world("Світ");
// явний виклик конструктора string exclamation'!'>;
// ініціалізація як масиву символів cout
<" "
<>;
return
0;
>
Висновок цієї програми:
Тепер давайте розберемо, що робить ця програма:
- в рядку 6 ми присвоюємо значення змінної типу string з допомогою оператора = . Цей варіант ви зустрічатимете найчастіше.
- в рядку 7 ми явно викликаємо конструктор string і передаємо туди потрібний рядок.
- в рядку 8 ми використовуємо той факт, що рядок працює як вектор символів, тому ми можемо використовувати конструкцію виду , , . >.
- в рядку 10 ми виводимо рядки на екран використовуючи стандартний cout.
Тепер розглянемо операції, які ми можемо проводити над рядками.
Об'єднання рядків (конкатенація)
Щоб з'єднати два рядки, достатньо скористатися оператором + :
string c =
"С"; string pp =
"++"; string cpp = c + pp; cout
"cpp token operator"> cpp endl;
При цьому не обов'язково поєднувати значення з кількох змінних. Ми можемо об'єднати рядок з рядком "рядок у форматі C" (масивом символів char[] ):
string c =
"С"; string cpp = c +
"++"; cout
"cpp token operator"> cpp endl;
Не можна з'єднати два рядкові літерали "C" + "++", оскільки оператор + не визначений на масивах типу char[]. Для того щоб скласти два рядки за допомогою +, обов'язково на одній із сторін оператора + повинен знаходитись рядок string.
Висновок програми ідентичний попередньому:
Крім оператора + є метод append, який дозволяє додати один рядок до іншого:
string lang =
"С"; lang.append("++"); cout
"lang token operator"> lang endl;
Відмінність методу append + полягає в тому, що append змінює існуючий рядок, в той час як + створює новий.
Оскільки append змінює існуючий рядок, він працює швидше, ніж + особливо при багаторазових злитті рядків.
Варто зазначити, що не можна отримати суму чисел усередині рядка за допомогою оператора + . Давайте розглянемо приклад:
string a =
"12"; string b =
"34"; cout
"a + b token operator"> a + b endl;
Як ви бачите, додавання просто додало цифри одного рядка на кінець іншого. Якщо ми спробуємо скласти рядок із числом, то отримаємо помилку компіляції. Код у наступному прикладі не скомпілюється:
string a =
"12"; cout a +
34
endl;
// Invalid operands to binary expression ('std::string' and 'int')
Що буде виведено на екран:
string a =
"23"; string b =
"45"; cout a + b endl;
Коли два рядки конкатенуються за допомогою оператора + , їх вміст просто об'єднується. Таким чином, "23" + "45" дає "2345", а не математичну суму чисел.
Отримання довжини рядка
Щоб отримати довжину рядка, ми можемо скористатися методом length :
string s =
"C++"; cout
"s.length() token operator"> s.length()
endl;
У методу length є "брат-близнючок" - size :
string s =
"C++"; cout
"s.size() token operator">s.size()
endl;
Між ними немає різниці, тому ви можете вибрати назву методу на власний смак.
Отримання та зміна символу в рядку
string дозволяє нам отримувати будь-який символ за вказаним індексом за допомогою оператора []. При цьому можна також використовувати метод at, проте оператор [] є компактнішим і зустрічається частіше в реальних програмах:
string s =
"ABCDE"; cout
"s[1] token operator">s[1]
endl;
Перший символ у рядку має індекс 0 .
Так само, як і з масивами, ми можемо надати будь-якому осередку нове значення:
string s =
"ABCDE"; s[1]
=
'X'; cout
"s[1] token operator">s[1]
endl;
А як нам оголосити рядок, який складається з двох ліній? Для цього достатньо скористатися спеціальним символом \n:
string s =
"Перший рядок.\nДругий рядок"; cout s endl;
Перший рядок. Другий рядок
У C++ всі спеціальні символи в рядках починаються з \. Ось приклади спеціальних символів, що часто використовуються:
- \n - перенесення рядка
- \' - одинарна лапка
- \" - подвійна лапка
- \ - зворотний сліш
Що буде виведено на екран:
cout
"Привіт, світ\nПривіт знову!"
endl;
У C++ всі спеціальні символи в рядках починаються з \. \ використовується для виведення зворотного слішу. Тому висновок буде “Привіт, мир Привіт знову!” без переходу на новий рядок.
Введення рядків із консолі використовуючи cin
cin дозволяє нам вводити рядки безпосередньо з консолі. Для цього достатньо вказати змінну типу string, в яку буде записано рядок, введений користувачем:
string name; cout
"Введіть ваше ім'я:"; cin >> name; cout
"Ваше ім'я:"
name endl;
Приклад роботи програми:
Введіть ваше ім'я: Діма Ваше ім'я: Діма
Однак, якщо ми спробуємо ввести рядок із пробілом, то cin вважає рядок лише до першого пробілу. Якщо ми хочемо вважати рядок повністю, потрібно використовувати функцію getline:
string name; cout
"Введіть ваше ім'я: ";
getline(cin, name); cout
"Ваше ім'я:"
name endl;
Приклад роботи програми:
Введіть ваше ім'я: Вася Пупкін Ваше ім'я: Вася Пупкін
Тепер давайте познайомимося докладніше з методами, які є у string.
Ми вже бачили кілька методів: length, size та append. Однак рядки мають ще багато корисних функцій, які спростять вам життя:
- begin/end - отримати ітератор для рядка
- empty – перевірка на порожнечу
- clear - очищення рядка
- front/back - отримати перший/останній символ
- insert - вставити підрядок
- erase - видалити підрядок
- replace - змінити підрядок
- find - знайти підрядок
- compare - порівняти два рядки
string - це контейнер C++. Як і інші контейнери C++, він надає можливість обходу своїх елементів. Для цього можна використовувати ітератори, які отримуються за допомогою методів begin і end:
string s =
"123";
for
(auto it = s.begin(); it != s.end(); it++)
cout
<*it
<" ";
>
Висновок цієї програми:
Щоб отримати висновок 3 2 1 потрібно використовувати методи rbegin / rend замість begin / end .
Замість писати s.length() == 0 , ми можемо скористатися методом empty :
string s =
""; cout
"s token operator"> (s.empty()
?
""
: s)
endl;
Метод clear дозволяє нам очистити існуючий рядок:
string s =
"Довгий рядок"; cout
"s token operator">s endl; s.clear(); cout
"s token operator"> (s.empty()
?
""
: s)
endl;
s = Довгий рядок s =
Замість звернення до індексів 0 і s.length() - 1 безпосередньо можна скористатися методами front і back :
string s =
"12345"; cout
"front token operator">s.front()
endl; cout
"back token operator">s.back()
endl;
Метод insert дозволяє нам додати символи до будь-якої частини існуючого рядка:
string s =
"125"; s.insert(2,
"34"); cout
"s token operator">s endl;
Перший аргумент методу insert вказує, куди вставити. Другий аргумент - це підрядок, який слід вставити за вказаним індексом.
Метод erase видаляє частину рядка:
string s =
"123__45"; s.erase(3,
2); cout
"s token operator">s endl;
erase приймає два аргументи:
- позиція, з якої починати видаляти
- скільки символів потрібно видалити
Метод replace є комбінацією методів erase і insert:
string s =
"12__5"; s.replace(2,
2,
"34"); cout
"s token operator">s endl;
Метод replace приймає:
- позиція, з якої починати заміну
- кількість символів, які потрібно замінити
- рядок, на який потрібно замінити
Метод find дозволяє нам знайти підрядок в іншому рядку. Цей метод приймає рядок, який потрібно знайти. Якщо рядок вдалося знайти, ми отримаємо індекс першого входження даної підрядки. Якщо ж підрядок знайти не вдалося, find поверне -1:
string s =
"Не май сто рублів, а май сто друзів.";
int index = s.find("сто"); cout
"індекс першого входження "сто" token operator"> index endl; index = s.find("мільйон"); cout
"index token operator">index endl;
Висновок цієї програми:
індекс першого входження "сто" = 14 index = -1
Вас може здивувати індекс входження підрядка сто. Справа в тому, що string зберігає набір байт. Російські символи займають два байти на відміну від пробілу чи цифр. Виходить: "Ні" - 4 байти, "" - 1 байт, "май" - 8 байт, "" - 1 байт. У сумі – 14 байт. Ви можете докладніше почитати, чому різні символи використовують різну кількість байт у статті про UTF-8.
Що буде виведено на екран:
string s =
"Привіт, мир!";
int index = s.find("світ"); cout
"index token operator">index endl;
У рядку "Привіт, мир!" підрядок “світ” починається після “Привіт,”. “Привіт,” займає 14 байт (2 * 6 байти для слова “Привіт” і 2 байти на кому з пропуском), тому index дорівнює 14 .
Закінчимо ми на методі compare. Даний метод дозволяє нам порівняти два рядки і дізнатися, який з них лексикографічно більше. a.compare(b) поверне:
Ось наочний приклад:
string a =
"123"; string b =
"43"; string c =
"1234"; cout
"123.compare(123 ) token operator"> a.compare(a)
endl; cout
"123.compare(43 ) token operator"> a.compare(b)
endl; cout
"123.compare(1234) token operator"> a.compare(c)
endl; cout
"43 .compare(1234) token operator"> b.compare(c)
endl;
123.compare(123 ) = 0 123.compare(43 ) = -1 123.compare(1234) = -1 43 .compare(1234) = 1
Якщо висновок вам здається неправильним, я раджу почитати про лексикографічний порядок за посиланням вище.
- Використання front та back :
Напишіть програму, яка:
- Запитує у користувача рядок.
- Використовуючи методи front і back, виводить на екран перший та останній символи цього рядка.
- Редагування рядка:
Розробте програму, яка:
- Запитує користувача вихідний рядок.
- Надає меню з 4 опціями: insert, erase, replace, і find.
- Залежно від вибору користувача програма надає інструкції для використання відповідного методу та виводить результат.
- Порівняння рядків за допомогою compare :
Напишіть програму, яка:
- Запитує у користувача два рядки.
- Використовує метод compare для порівняння цих рядків.
- Виводить на екран результат порівняння (який рядок лексикографічно більший, або якщо вони рівні).
Якщо хочете завжди бути в курсі останніх новин у світі програмування та IT, підписуєтеся на мій Telegram-канал, де я поділяюся свіжими статтями, новинами та корисними порадами. Радий бачити вас серед передплатників!
Читайте також
C++ надає безліч способів пошуку рядків. Метод string::find - один з методів, що найчастіше використовуються для пошуку підрядків.У цій статті ви дізнаєтеся, як ефективно використовувати цей метод, зрозумієте його поведінку на різних прикладах і навіть напишете просту власну функцію пошуку в рядку.
Функція sprintf – це близький аналог функції printf. Основна відмінність між ними полягає в тому, що sprintf не виводить відформатований рядок на екран, а записує його за вказаною адресою. Ця функція часто використовується C/C++ і рекомендується до вивчення.
Функція snprintf використовується у мовах C і C++ для форматування рядка без виведення на екран. У статті буде розібрано приклади використання цієї функції. Також наприкінці статті є вправи.
Функція strncpy використовується у мовах C і C++ для копіювання Сі-рядків. Відмінність цієї функції від strcpy у тому, що вона копіює лише перші n байтів. У статті буде розібрано приклади використання цієї функції. Також наприкінці статті є вправи.
Функція strlen використовується в мові програмування C для розрахунку кількості символів у рядку. У статті буде розібрано приклади використання цієї функції. Також ми реалізуємо цю функцію самі, а наприкінці статті є вправи для закріплення матеріалу.
Функція puts використовується в мові програмування C для виведення рядка на екран, використовуючи стандартний висновок. У статті буде розібрано приклади використання цієї функції. Також ми реалізуємо цю функцію самі, а наприкінці статті є вправи для закріплення матеріалу.
У цьому уроці ви дізнаєтеся, що таке вектор у C++, а також якщо ви хочете дізнатися, як правильно користуватися і які функції до них застосовувати - вам сюди.
У цьому уроці ви дізнаєтеся, як використовувати функцію strcpy в C++ для копіювання рядків. Приклади та вправи допоможуть вам закріпити вивчене на практиці.
Функція strcmp використовується у мовах програмування C порівняння двох рядків. У статті буде розібрано приклади використання цієї функції. Також ми реалізуємо цю функцію самі, а наприкінці статті є вправи для закріплення матеріалу.