c++ - 删除标点查询

标签 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))。

当您查看代码时,任何人都可以改进它或使其更高效吗?

谢谢

最佳答案

首先,这在一般情况下是行不通的;它似乎(而且它 可能适用于某些编译器)。您不能将 char 传递给 ispunct 的一个参数版本,不会产生 undefined 行为。

至于强制转换的原因:标准定义了两者 单个参数 ispunct 函数 and 两个参数 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 ) );
    }
};

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

关于c++ - 删除标点查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15967516/

相关文章:

c++ - Win7 对话框崩溃

c++ - 在不同的类上调用不同的成员函数

c++ - Poco C++ Websocket 服务器 - 防止它在 60 秒后关闭

c# - 检查给定字符串是否是用于转换 DateTime 的有效格式字符串

c# - 如何将数字格式化为没有百分号的百分比?

c++ - 将 error_info 添加到 std::exception

c++ - 如何模板化循环结构以用于多个内核

nested - Python 3 嵌套字符串格式

java - android java String.format 在 double 上小数点之前和之后填充零

python - 将传递的 arg 转换为字符串