3. Класс std::string
string::find_first_not_of
, она принимает строку, содержащую все символы, которые мы хотим опустить. В нашем случае таковыми являются символы пробела ' '
, табуляции '\t'
и перехода на новую строку '\n'
. Функция возвращает позицию первого символа, не совпадающего с переданными. При наличии в строке только пробелов она вернет значение string::npos
. Это значит следующее: если мы удалим все пробелы, то останется только пустая строка. Так что в подобных случаях просто возвращайте пустую строку: const char whitespace[] {" \t\n"};
const size_t first (s.find_first_not_of(whitespace));
if (string::npos == first) { return {}; }
4. Теперь мы знаем, где должна начинаться новая строка, но пока неизвестно, где она заканчивается. Поэтому воспользуемся другой полезной функцией строки: string::find_last_not_of
const size_t last (s.find_last_not_of(whitespace));
5. С помощью функции string::substr
return s.substr(first, (last - first + 1));
}
6. На этом все. Напишем функцию main
int main()
{
string s {" \t\n string surrounded by ugly"
" whitespace \t\n "};
7. Выведем на экран необрезанную и обрезанную версии строки. Окружив строку скобками, можно показать все пробелы, которые находились в ней до обрезки.
cout << "{" << s << "}\n";
cout << "{"
<< trim_whitespace_surrounding(s)
<< "}\n";
}
8. Компиляция и запуск программы дадут ожидаемый результат:
$ ./trim_whitespace
{
string surrounded by ugly whitespace
}
{string surrounded by ugly whitespace}
Как это работает
В этом разделе мы применили функции string::find_first_not_of
string::find_ last_not_of
. Обе принимают строку, созданную в стиле C, в виде списка символов, которые нужно проигнорировать при поиске другого символа. Если у нас есть экземпляр строки, содержащий строку "foo bar"
, и мы вызовем для него функцию find_first_not_of("bfo ")
, то она вернет значение 5
, поскольку символ 'a'
— первый символ, который не входит в строку "bfo"
. Порядок символов в строке-аргументе неважен.Существуют подобные функции с инвертированной логикой, однако мы не использовали их в этом примере:
string::find_first_of and string::find_last_of
По аналогии с функциями, основанными на итераторах, нужно проверять, возвращают ли эти функции реальную позицию в строке или же значение, которое указывает, что позиция символа, отвечающего условию,
string::npos
.На основе позиций символов, полученных из этих функций, мы в рамках вспомогательной функции создаем подстроку, не содержащую пробелов в начале и конце, с помощью функции string::substring
string{"abcdef"}.substr(2, 2)
вернет новую строку "cd"
.Преимущества использования std::string без затрат на создание объектов std::string
Класс std::string