尝试这个:
它使用本地过滤掉标点符号。
这允许其余代码保持不变。
#include <locale>
#include <string>
#include <iostream>
#include <fstream>
#include <cctype>
class PunctRemove: public std::codecvt<char,char,std::char_traits<char>::state_type>
{
bool do_always_noconv() const throw() { return false;}
int do_encoding() const throw() { return true; }
typedef std::codecvt<char,char,std::char_traits<char>::state_type> MyType;
typedef MyType::state_type state_type;
typedef MyType::result result;
virtual result do_in(state_type& s,
const char* from,const char* from_end,const char*& from_next,
char* to, char* to_limit, char*& to_next ) const
{
/*
* This function is used to filter the input
*/
for(from_next = from, to_next = to;from_next != from_end;++from_next)
{
if (!std::ispunct(*from_next))
{
*to_next = *from_from;
++to_next;
}
}
return ok;
}
/*
* This function is used to filter the output
*/
virtual result do_out(state_type& state,
const char* from, const char* from_end, const char*& from_next,
char* to, char* to_limit, char*& to_next ) const
{ /* I think you can guess this */ }
};
int main()
{
// stream must be imbued before they are opened.
// Otherwise the imbing is ignored.
//
std::ifstream data;
data.imbue(std::locale(std::locale(), new PunctRemove));
data.open("plop");
if (!data)
{
std::cout << "Failed to open plop\n";
return 1;
}
std::string line;
std::getline(data, line);
std::cout << "L(" << line << ")\n";
}