删除标点符号查询

时间:2013-04-12 09:20:01

标签: c++ string-formatting

我一直在更新我差不多两年前编写的程序,并且我遇到了一个从字符串中删除所有标点符号和空格的调用。

通话工作正常,但我不确定这是最有效的方式。

代码行如下:

tempMessage.erase(remove_if(tempMessage.begin(), tempMessage.end(), (int(*)(int))ispunct), tempMessage.end());

我不记得我在哪里提出这个或如何组合在一起,但我希望能够完全理解这个电话。

我得到了std :: string.erase在第二个参数之前删除了第一个参数。我还可以看到remove_if如何定义起点和终点,但有人能告诉我remove_if调用中的第三个参数来自哪里?

我不记得为什么生命中需要(int(*)(int))。

在查看代码时,是否有人可以改进此代码,或者提高效率?

谢谢

1 个答案:

答案 0 :(得分:1)

首先,这不起作用;它似乎(和它 可能适用于某些编译器)。您无法将char传递给 ispunct的一个参数版本,不会产生未定义的 行为。

关于演员阵容的原因:标准定义了两者 单个参数ispunct函数两个参数 ispunct功能模板。为了正确 实例化模板函数erase,编译器需要 要知道ispunct的确切类型。要知道确切的类型 ispunct,编译器需要能够进行类型推导 功能模板。为了做类型演绎, 编译器需要知道预期的类型。有个循环 依赖关系,明确表达(或看起来像什么) 明确的演员表决定。

因为使用ispunct的单参数版本会导致 未定义的行为,并且使用两个参数版本不会 编译,除非您提供附加参数(使用 例如std::bind,任何进行任何字符串处理的人 C ++将在其工具箱中编写功能对象 处理这个问题,并写下类似的东西:

tempMessage.erase(
    std::remove_if( tempMessage.begin(), tempMessage.end(), IsPunct() ),
    tempMessage.end() );

如何实施IsPunct取决于您的需求 本地化。最简单的版本就是:

struct IsPunct
{
    bool operator()( char ch ) const
    {
        return ::ispunct( static_cast<unsigned char>( ch ) );
    }
};

使用ctype locale方面的版本有点儿 更复杂(你可能希望它保留一份副本 locale,以及对方面的参考,只是为了确定 引用的facet不会消失。)