#cpp #строки
Допустим есть строка с именем процессора, которую возвращает функция GetProcessorName(): // "IntelCore 2 Duo CPU P8400 @ 2.26GHz" std::string some_string = GetProcessorName(); Необходимо убрать лишние пробелы. То есть, отформатировать строку так, чтобы между словами не было лишних пробелов или знаков табуляции. Вот так: // "Intel Core 2 Duo CPU P8400 @ 2.26GHz"; Пробовал replace & replace_if, в конце-концов понял, что эти и подобные им алгоритмы предназначены исключительно для контейнеров. Возможно лямбды помогут. Что посоветуете делать с std::string?
Ответы
Ответ 1
вообще то std::string - это обычный контейнер. такой же, как обычный std::vector. Если не хочется remove/remove_if и душа требует лямбд, можно так #include#include #include using namespace std; int main() { std::string some_string = "Intel Core 2 Duo CPU P8400 @ 2.26GHz"; auto end = std::unique(some_string.begin(), some_string.end(), [](char l, char r){ return std::isspace(l) && std::isspace(r) && l == r; }); std::cout << std::string(some_string.begin(), end) << '\n'; return 0; } UPD Некоторые предлагают переписать условие std::isspace(l) && std::isspace(r) && l == r как std::isspace(l) && l == r я бы его все таки переписал как std::isspace(l) && std::isspace(r) Почему? В вопросе звучит "удалить лишние пробелы и табы". А если строка такая (символ подчеркивания - это пробел, а \t - табуляция) a\t\t__\t_\tb то ее наверно правильно было бы сократить до a_b, а не a\t_\t_\tb. Но если посмотреть, что именно проверяет std::isspace, то узнаете, что перевод строки (\n) также считается. Поэтому, если строка будет многострочной вида abc_\n_def, то она будет сокращена до abc_def, что может быть не совсем то, что хочется. Кстати, это вариант ближе к варианту с регуляркой в ответе @GreenDragon, так как \s работает как isspace. Ответ 2
Ну а чем string не контейнер? :) Сами убедитесь: int main(int argc, const char * argv[]) { string s = "IntelCore 2 Duo CPU P8400 @ 2.26GHz"; s = s.substr(0,distance(s.begin(),remove_if(s.begin(), s.end(), [](const char& a) { return (a == ' ') && (*(&a+1) == ' '); }))); cout << "[" << s << "]\n"; } Ответ 3
Для работы с текстом можно использовать регулярные выражения. Начиная с C++11 в стандартной библиотеке появилась их поддержка, поэтому вашу задачу также можно решить следующим способом: #include#include #include int main() { std::string str= "Intel Core 2 Duo CPU P8400 @ 2.26GHz"; std::regex e("(\\s)+"); std::cout << std::regex_replace (str,e,"$1")<<"\n"; } Ответ 4
Немного упрощенный вариант кода @KoVadim под c++03: #include#include #include #include bool space2(char l, char r) { return l == r && std::isspace(l); } int main() { std::string s = "Intel Core 2 Duo CPU P8400 @ 2.26GHz"; std::cout << std::string(s.begin(), std::unique(s.begin(), s.end(), space2)) << '\n'; }
Комментариев нет:
Отправить комментарий