Существуют ли современные альтернативы std :: strchr () для C ++? - PullRequest
3 голосов
/ 20 сентября 2019

Я широко использую 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 ]

3 голосов
/ 20 сентября 2019

Нет смысла обновлять ваш код, потому что строковый литерал имеет тип символьного массива.

Было бы плохой идеей создать промежуточный объект, например, 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 в качестве параметра функции.

3 голосов
/ 20 сентября 2019

Вы можете использовать std::find со строкой или std::string с собственной std :: string :: find .

1 голос
/ 20 сентября 2019

Если вы можете сохранить строку C в массиве, вы можете использовать std::find примерно так:

constexpr char charset[] = "abcd";
while (std::find(std::begin(charset), std::end(charset), input) 
       == std::end(charset)) 
{...}
0 голосов
/ 20 сентября 2019

Вы можете использовать std::string find_first_of.Пример:

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

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

Но если вы не хотите создавать новый std::string объект, strstr - это путь.Но обратите внимание, что это имеет удар по производительности.

...