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