Использование библиотеки 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> можно упорядочивать стандартными методами. Строки сравниваются в лексикографическом порядке.