Для тех, кто не так мудр, вот функции ANSI и UNICODE, основанные на ответе Эрика Маленфанта:
std::string CleanString(const std::string& Input)
{
std::string clean_string;
std::locale loc;
try {
std::remove_copy_if(Input.begin(), Input.end(), std::back_inserter(clean_string),
!(boost::bind(&std::isalnum<unsigned char>, _1, loc) || boost::bind(&std::isspace<unsigned char>, _1, loc)
));
}
catch (const std::bad_alloc& e) {
std::cout << "Allocation failed: " << e.what() << '\n';
}
return clean_string;
}
std::wstring CleanString(const std::wstring& Input)
{
std::wstring clean_string;
std::locale loc;
try {
std::remove_copy_if(Input.begin(), Input.end(), std::back_inserter(clean_string),
!(boost::bind(&std::isalnum<wchar_t>, _1, loc) ||
boost::bind(&std::isspace<wchar_t>, _1, loc)
));
} catch (const std::bad_alloc& e) {
std::cout << "Allocation failed: " << e.what() << '\n';
}
return clean_string;
}
Демонстрация в сети: https://wandbox.org/permlink/MFTwXV4ZCi9nsdlC
Полный тестовый код для Linux:
#include <iostream>
#include <algorithm>
#include <cctype>
#include <boost/bind.hpp>
// Note on Linux we use char and not unsigned char!
std::string CleanString(const std::string& Input)
{
std::string clean_string;
std::locale loc;
try {
std::remove_copy_if(Input.begin(), Input.end(), std::back_inserter(clean_string),
!(boost::bind(&std::isalnum<char>, _1, loc) || boost::bind(&std::isspace<char>, _1, loc)
));
}
catch (const std::bad_alloc& e) {
std::cout << "Allocation failed: " << e.what() << '\n';
}
catch (...)
{
}
return clean_string;
}
std::wstring CleanString(const std::wstring& Input)
{
std::wstring clean_string;
std::locale loc;
try {
std::remove_copy_if(Input.begin(), Input.end(), std::back_inserter(clean_string),
!(boost::bind(&std::isalnum<wchar_t>, _1, loc) ||
boost::bind(&std::isspace<wchar_t>, _1, loc)
));
}
catch (const std::bad_alloc& e) {
std::cout << "Allocation failed: " << e.what() << '\n';
}
catch (...)
{
}
return clean_string;
}
int main()
{
std::string test_1 = "Bla=bla =&*\n Sample Sample Sample !$%^&*@~";
std::string new_test_1 = CleanString(test_1);
if (!new_test_1.empty())
{
std::cout << "ANSI: " << new_test_1 << std::endl;
}
std::wstring test_uc_1 = L"!$%^&*@~ test &*";
std::wstring new_test_uc_1 = CleanString(test_uc_1);
if (!new_test_uc_1.empty())
{
std::wcout << L"UNICODE: " << new_test_uc_1 << std::endl;
}
return 0;
}
Благодаря Эрику Маленфанту.