C++ 是否有 std::strchr() 的现代替代品?

Are there any modern alternatives of std::strchr() for C++?

我在我的代码中广泛使用 std::strchr(),但最近我开始考虑让我的代码更具可读性和现代性。我希望有类似于 std::any_of/std::string::find_first_of 的功能,它采用单个字符而不是容器。所以我在问自己如何 "update" 我的代码到 C++17。

while (std::strchr("abcd", input) == nullptr) { //how to get rid of this C function?
        //do smth
}

有什么想法吗?

谢谢,祝你有个愉快的一天!

您可以将 std::find 与字符串一起使用,或者 std::string 自己的 std::string::find

您可以使用 std::stringfind_first_of。示例:

std::string string{"abcdefglrkemf..."};

while (string.find_first_of("def") != std::string::npos)
    //...

但是如果您不想创建新的 std::string 对象,strstr 是可行的方法。但请注意,这会影响性能。

更新您的代码没有意义,因为字符串文字具有字符数组类型。

创建一个中间对象 std::string 来执行这样一个简单的任务是个坏主意。

像数组一样声明的 C 字符串使用 C 字符串函数。 C 字符串函数经过优化,有时仅使用一对机器指令即可执行。

与其他容器一起使用它们的成员函数或标准算法。

例如比较两种方法

const char *s = "abcd";

const char *p = strchr( s, c );

if ( p )
{
    //...
}

甚至喜欢

const char *s = "abcd";

if ( const char *p = strchr( s, c ) )
{
    //...
}

const char *s = "abcd";
size_t n = std::strlen( s );

auto it = std::find( s, s + n, c );

if ( it != s + n )
{
    //...
}

或在 C++ 17 中可读性较差

const char *s = "abcd";
size_t n = std::strlen( s );

if ( auto it = std::find( s, s + n, c ); it != s + n )
{
    //...
}

显然第一种方法效率更高。

另一方面,如果您有一个应该接受 C 字符串的通用函数 and/or 类型 std::string 的对象,然后如果函数不更改它​​们,则使用 std::string_view 作为函数参数。

如果可以将 C 字符串存储在数组中,则可以像这样使用 std::find

constexpr char charset[] = "abcd";
while (std::find(std::begin(charset), std::end(charset), input) 
       == std::end(charset)) 
{...}

看起来 strchr 的现代 c++ 替代品是 std::char_traits<char>::find。它也是 constexpr!

while (std::char_traits<char>::find("abcd", input) == nullptr) { //how to get rid of this C function?
    //do smth
}

但是,我不确定这是否比您已有的更具可读性。 如果您的目标纯粹是可读性,那么使用薄内联包装器包装标准库函数没有错。

inline bool DoesStringContainSubstring(const char* str, const char* subStr) { return std::strchr(str, subStr) != nullptr; }