3

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

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

有任何想法吗?

谢谢,祝你有美好的一天!

4

5 回答 5

3

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

于 2019-09-20T15:41:38.733 回答
3

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

创建一个例如 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 字符串和/或类型的对象的通用函数,std::string那么如果该函数不更改它​​们,则将其std::string_view用作函数参数。

于 2019-09-20T15:48:21.927 回答
1

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

constexpr char charset[] = "abcd";
while (std::find(std::begin(charset), std::end(charset), input) 
       == std::end(charset)) 
{...}
于 2019-09-20T15:54:36.277 回答
0

您可以使用std::string's find_first_of。例子:

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

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

但是,如果您不想创建新std::string对象,strstr那就是要走的路。但请注意,这会影响性能。

于 2019-09-20T15:46:43.317 回答
0

它看起来像是 is 的现代 c++ 替代strchrstd::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; }
于 2019-12-05T10:30:03.570 回答