Использование библиотеки STL
Контейнер для строк: string
В STL существует специальный контейнер для работы со строками: string. Этот контейнер не очень сильно отличается от vector<char>. Различия, в основном, сосредоточены в функциях для манипулирования строками и в политике работы с памятью. Для того, чтобы узнать длину строки, принято использовать string::length(), а не vector::size().
У строк есть метод substr для быстрого получения подстроки в виде отдельной строки. Этот метод принимает в качестве параметров только индексы, и никаких итераторов:
string s = "hello"; string s1 = s.substr(0, 3), // "hel" s2 = s.substr(1, 3), // "ell" s3 = s.substr(0, s.length()-1), "hell" s4 = s.substr(1); // "ello"Как и в случае с vector::size(), string::length() возвращает беззнаковый тип. Поэтому будьте аккуратны с конструкциями вроде (s.length()-1): для пустой строки s результат, скорее всего, не оправдает ваших ожиданий.
Также бывает удобным использовать метод string::find(). Он возвращает индекс начала первого вхождения символа или строки.
Кроме string::find, бывает удобно использовать метод string::find_first_of. Если передать в качестве параметра find_first_of один символ, вызов find_first_of будет полностью аналогичен вызову find. Однако, если передать в качестве параметра find_first_of строку, метод вернёт индекс первого вхождения любого символа из данной строки:
string s = "Hello, World!";
int index = s.find_first_of(' '); // поиск первого пробела
int index2 = s.find_first_of(", !"); // поиск первого пробела,
//знака восклицания или запятой
Особенно find_first_of удобно использовать для того, чтобы разделить строку на множество строк. Это актуально, потому как встроенных функций для string splitting в STL, к сожалению, нет.
// разбить строку на вектор строк,
// используя пробелы и запятые как разделители
vector<string> v;
size_t i;
while((i = s.find_first_of(", ")) != string::npos) {
// кусок строки до первого разделителя
v.push_back(s.substr(0, i));
// вырезать вместе с разделителем
s = s.substr(i+1);
}
v.push_back(s); // дописать остаток строки
Строки можно складывать с помощью оператора +:
string s = "hello";
string
s1 = s.substr(0, 3), // "hel"
s2 = s + s1; // " helloell"
Строки можно складывать с помощью оператора + и с символами, но нужно быть аккуратными
с константными строками. Запись "jdklasj" -- это переменная типа const char*.
В большинстве случаев, но не всегда, объекты типа const char* по мере необходимости
приводятся к типу string напрямую. Этого не происходит лишь в одном случае: складывать
две константных строки нельзя. Для этого нужно привести первую из них к типу string напрямую.
Впрочем, если обе строки -- действительно константные, можно просто опустить знак +.
У string нет конструктора от одного char. Для того, чтобы создать строку, состоящую из одного символа, можно либо добавить этот символ к пустой строке (string("") + 'A'), либо использовать инициализацию в стиле vector: string(1, 'B'). Соответственно, таким же образом создаются строки, состоящие из фиксированного числа одинаковых символов.
В общем случае лучше работать с типом string, чем с const char*. Иначе может так случиться, что компилятор подумает совсем не то, что вы имели в виду:
string s = "word", s2;
s = 'S' + s + '!'; // "Sword!"
s2 = 'A' + " and " + 'B';
//таких конструкций следует избегать. фактически здесь мы
//к числу типа char прибавили указатель, а потом еще раз число
s2 = 'X' + string(" and ") + 'Y';
// "X and Y" √-- это корректно
string s3wrong = "p " + " and q "; // не компилируется
string s3 = "p" " and q"; // так можно,
//но всегда проще написать string("p") + ' ' + "and q";
Также строки можно сравнивать с помощью операторов сравнения. Таким образом, vector<string> можно упорядочивать стандартными методами. Строки сравниваются в лексикографическом порядке.