Допустим есть строка с именем процессора, которую возвращает функция GetProcessorName()
:
// "Intel<R> Core<TM>2 Duo CPU P8400 @ 2.26GHz"
std::string some_string = GetProcessorName();
Необходимо убрать лишние пробелы. То есть, отформатировать строку так, чтобы между словами не было лишних пробелов или знаков табуляции. Вот так:
// "Intel<R> Core<TM>2 Duo CPU P8400 @ 2.26GHz";
Пробовал replace
& replace_if
, в конце-концов понял, что эти и подобные им алгоритмы предназначены исключительно для контейнеров. Возможно лямбды помогут. Что посоветуете делать с std::string
?
вообще то std::string
- это обычный контейнер. такой же, как обычный std::vector
.
Если не хочется remove
/remove_if
и душа требует лямбд, можно так
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main() {
std::string some_string = "Intel<R> Core<TM>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
.
Ну а чем string
не контейнер? :)
Сами убедитесь:
int main(int argc, const char * argv[])
{
string s = "Intel<R> Core<TM>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";
}
Немного упрощенный вариант кода @KoVadim под c++03:
#include <iostream>
#include <algorithm>
#include <string>
#include <cctype>
bool space2(char l, char r) {
return l == r && std::isspace(l);
}
int main() {
std::string s = "Intel<R> Core<TM>2 Duo CPU P8400 @ 2.26GHz";
std::cout << std::string(s.begin(), std::unique(s.begin(), s.end(), space2)) << '\n';
}
Для работы с текстом можно использовать регулярные выражения. Начиная с C++11 в стандартной библиотеке появилась их поддержка, поэтому вашу задачу также можно решить следующим способом:
#include <iostream>
#include <string>
#include <regex>
int main()
{
std::string str= "Intel<R> Core<TM>2 Duo CPU P8400 @ 2.26GHz";
std::regex e("(\\s)+");
std::cout << std::regex_replace (str,e,"$1")<<"\n";
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Есть два приложения которые работают параллельно (условно 1 и 2)Приложение 2 написано на С++(Qt)
Есть конструктор, который принимает строку-число, цифры которого записывает в массив numberПри выводе данного массива получаю почему-то рандомные...
В примере асинхронного tcp-сервера на бусте связывается функция (все это происходит в классе, наследующим enable_shared_from_this):