Получение и изменение символов строки
Строки
В самом общем виде строка представляет собой массив символов, т.е. элементы такого массива имеют символьный тип char или wchar _ t (char 16_ t и char 32_ t используются намного реже). Тем не менее, обработка строк имеет свою специфику, связанную с тем, что количество символов в строке (длина строки) обычно становится известным только после того, как строка уже введена, а различные действия над строкой часто приводят к изменению её длины.
Как уже говорилось, в С++ имеется два основных способа работы со строками, основанных на разных способах их представления в памяти:
1. использование строк с завершающим нулём (С-строк) – способ, доставшийся в наследство от языка С, при котором строка описывается как обычный символьный массив, размер которого определяется исходя из ограничений задачи на максимальный размер вводимого текста;
2. использование типов string и wstring, определённых в стандартной библиотеке С++, не накладывающих ограничений на размер текста; для каких-то задач обработки текстов можно использовать и тип vector<char> (vector<wchar_t>).
Для использования типа string его необходимо подключить в код с помощью директивы include:
#include <string>
#include <iostream>
using namespace std;
int main()
{
string hello = "Hello World!";
cout << hello << "\n";
return 0;
}
Тип string определен в стандартной библиотеке и при его использовании надо указывать пространство имен std.
|
|
Либо можно использовать выражение using, чтобы не указывать префикс std:
1 | using namespace std; |
В данном случае значение переменной hello, которая представляет тип string, выводится на консоль.
Для инициализации строк можно использовать различные способы:
#include <string>
#include <iostream>
using namespace std;
int main()
{
string s1; // пустая строка
string s2 = "hello"; // hello
string s3("welcome"); // welcome
string s4(5, 'h'); // hhhhh
string s5 = s2; // hello
cout << s1 << "\n";
cout << s2 << "\n";
cout << s3 << "\n";
cout << s4 << "\n";
cout << s5 << "\n";
return 0;
}
Консольный вывод данной программы:
Если при определении переменной типа string не присваивать ей никакого значения, то по умолчанию данная переменная содержит пустую строку:
string s1;
Также можно инициализировать переменную строчным литералом, который заключается в двойные кавычки:
string s2 = "hello";
В качестве альтернативы можно передавать строку в скобках после определения переменной:
string s3("welcome");
Если необходимо, чтобы строка содержала определенное количество определенных символов, то можно указать в скобках количество символов и сам символ:
|
|
string s4(5, 'h');
И также можно передать переменной копию другой строки:
string s5 = s2;
Конкатенация строк
Над строками можно выполнять ряд операций. В частности, можно объединять строки с помощью стандартной операции сложения:
#include <iostream>
using namespace std;
int main()
{
string s1 = "hello";
string s2 = "world";
string s3 = s1 + " " + s2; // hello world
cout << s3 << endl;
return 0;
}
Сравнение строк
К строкам можно применять операции сравнения. Оператор == возвращает true, если все символы обеих строк равны.
string s1 = "hello";
string s2 = "world";
bool result = s1 == s2; // false
result = s1 == "Hello"; // false
result = s1 == "hello"; // true
При этом символы должны совпадать в том числе по регистру.
Операция != возвращает true, если две строки не совпадают.
string s1 = "hello";
string s2 = "world";
bool result = s1 != s2; // true
result = s1 != "Hello"; // true
result = s1 != "hello"; // false
Остальные базовые операции сравнения <, <=, >, >= сравнивают строки в зависимости от регистра и алфавитного порядка символов. Например, строка "b" условно больше строки "a", так как символ b по алфавиту идет после символа a. А строка "a" больше строки "A". Если первые символы строки равны, то сравниваются последующие символы:
|
|
string s1 = "Aport";
string s2 = "Apricot";
bool result = s1 > s2; // false
В данном случае условие s1 > s2 ложно, то есть s2 больше чем s1, так как при равенстве первых двух символов ("Ap") третий символ второй строки ("o") стоит в алфавите до третьего символа второй строки ("p"), то есть "o" меньше чем "p".
Размер строки
С помощью метода size() можно узнать размер строки, то есть из скольких символов она состоит:
string s1 = "hello";
cout << s1.size() << endl; // 5
Если строка пустая, то она содержит 0 символов. В этом случае мы можем применить метод empty() - он возвращает true, если строка пустая:
string s1 = "";
if(s1.empty())
cout << "String is empty" << endl;
Чтение строки с консоли
Для считывания введенной строки с консоли можно использовать объект cin:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
cout << "Input your name: ";
cin >> name;
cout << "Your name: " << name << endl;
return 0;
}
Консольный вывод:
Однако если при данном способе ввода строка будет содержать подстроки, разделенные пробелом, то std::cin будет использовать только первую подстроку:
Чтобы считать всю строку, применяется метод getline():
|
|
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
cout << "Input your name: ";
getline(cin, name);
cout << "Your name: " << name << endl;
return 0;
}
Метод getline принимает два объекта - cin и переменную, в которую надо считать строку.
Консольный вывод:
Получение и изменение символов строки
Подобно массиву можно обращаться с помощью индексов к отдельным символам строки, получать и изменять их:
string hello = "Hello";
char c = hello[1]; // e
hello[0]='M';
cout << hello << endl; // Mello
Символьные массивы
Массив символов, последний элемент которого представляет нулевой символ '\0', может использоваться как строка:
#include <iostream>
using namespace std;
int main()
{
char letters[] = {'h', 'e', 'l', 'l', 'o', '\0'};
cout << letters << endl;
return 0;
}
Данный код выведет на консоль строку "hello". Подобное определение массива строк будет также эквивалентно следующему:
char letters[] = "hello";
Следующий пример – демонстрация того, что строку можно обрабатывать как обычный массив символов, не забывая про завершающий нуль.
Пусть требуется удалить все пробелы из введённой строки текста.
Поскольку удаление каждого символа из массива – длительная операция перемещения всех следующих за ним символов, то возникает вопрос, как сократить число перемещений при удалении всех разбросанных по строке пробелов. Первое решение приходит в голову сразу – использовать вспомогательную строку, в которую переписать все символы, кроме пробелов. Разумеется, потом вспомогательная строка копируется в исходную.
Пример – удаление пробелов из строки
// с использованием вспомогательной строки
#include <iostream>
using namespace std;
int main()
{
int r=0,i=0; char s[80],s1[80];
cout<<"?"; cin.getline(s,80);
// перепишем в s1 все символы, кроме пробелов
for(i=0;s[i]!=0;i++)
if (s[i]!=' ') s1[r++]=s[i];
s1[r]=0; // нельзя забыть про завершающий нуль
for (i=0;s1[i]!=0;i++) s[i]=s1[i];
s[i]=0; // скопировали s1 обратно в s
cout<<s<<endl; system("pause"); return 0;
}
Первый пришедший в голову вариант не всегда самый лучший. Немного подумав, можно представить более эффективный вариант, который удаляет пробелы и без использования вспомогательной строки:
Пример – удаление пробелов из строки
// без использования вспомогательной строки
#include <iostream>
using namespace std;
int main()
{
int r=0,i=0; char s[80];
cout<<"?"; cin.getline(s,80);
for (i = 0; s[i] != 0 && s[i] != ' '; i++);// ищем первый пробел
for (int j = i; s[j] != 0; j++) {
if (s[j] != ' ') {
s[i] = s[j];// передвигаем символы внутри строки
i++;
}
}
s[i] = 0;
cout<<s<<endl; system("pause"); return 0;
}
Этот вариант можно ускорить только использованием указателей вместо индексов.
Управление строками C-style
C++ предоставляет множество функций для управления строками C-style, которые подключаются с помощью заголовочного файла cstring. Вот несколько самых полезных функций:
Функция strcpy_s() позволяет копировать содержимое одной строки в другую. Чаще всего это используется для присваивания значений строке:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char text[] = "Print this!";
char dest[50];
strcpy_s(dest, text);
cout << dest; // выводим "Print this!"
return 0;
}
Тем не менее, использование strcpy_s() может легко вызвать переполнение массива, если не быть осторожным! В следующей программе, длина массива dest меньше длины копируемой строки, поэтому в результате мы получим переполнение массива:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char text[] = "Print this!";
char dest[5]; // обратите внимание, длина массива dest всего 5 символов!
strcpy_s(dest, text); // переполнение!
cout << dest;
return 0;
}
Ещё одной полезной функцией управления строками является функция strlen(), которая возвращает длину строки C-style (без учёта нуль-терминатора):
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char name[15] = "Max"; // используется только 4 символа (3 буквы + нуль-терминатор)
cout << "My name is " << name << '\n';
cout << name << " has " << strlen(name) << " letters.\n";
cout << name << " has " << sizeof(name) << " characters in the array.\n";
return 0;
}
Результат выполнения программы выше:
Обратите внимание на разницу между strlen() и sizeof(). strlen() выводит количество символов до нуль-терминатора, тогда как оператор sizeof() возвращает размер целого массива, независимо от того, что в нём находится.
Вот ещё полезные функции для управления строками C-style:
strcat() — добавляет одну строку к другой (опасно);
strncat() — добавляет одну строку к другой (с проверкой размера места назначения);
strcmp() — сравнивает две строки (возвращает 0, если они равны);
strncmp() — сравнивает две строки до определённого количества символов (возвращает 0, если они равны).
Например:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
// Просим пользователя ввести строку
char buffer[255];
cout << "Enter a string: ";
cin.getline(buffer, 255);
int spacesFound = 0;
// Перебираем каждый символ, который ввёл пользователь
for (int index = 0; index < strlen(buffer); ++index)
{
// Подсчитываем количество пробелов
if (buffer[index] == ' ')
spacesFound++;
}
cout << "You typed " << spacesFound << " spaces!\n";
return 0;
}
Дата добавления: 2020-11-23; просмотров: 99; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!