Substr меняет позицию, в которой функция поиска начинает поиск? - PullRequest
0 голосов
/ 07 июня 2019

Изменяет ли substr положение, в котором функция поиска начинает поиск?

У меня есть символ * с именем search_text, содержащий следующий текст:

ABC_NAME = 'XYZSomeone' AND ABC_CLASS = 'XYZSomething'

Я хочу отобразить значение "ABC_NAME" из этой строки.

Вот что я делаю:

std::cout << std::string(search_text).substr ( 12, std::string( search_text ).find ("'", 13 )-1) << std::endl;

Моя логика в вышеуказанном в подстре выглядит следующим образом:

  1. Значение ABC_NAME всегда начинается с 12-го символа, поэтому начинайте с подстроки.
  2. Выполнить поиск для символа '(одиночная кавычка) начиная с 13-го символа и далее, начиная с 13-го символа (второй аргумент функции find ()). Полученное число будет внешней границей подстрока.

Однако мой код распечатывает следующее:

XYZSomeone' AND ABC_C

Однако, когда я пытаюсь отобразить значение функции find () напрямую, я получаю правильное число для местоположения второй '(одиночная кавычка)

std::cout << std::string( search_text ).find ("'", 13 ) << std::endl;

Это распечатывает:

22

Итак, почему substr не находит значение 22 в качестве второго аргумента?

1 Ответ

0 голосов
/ 08 июня 2019

Довольно просто оценить ваше выражение вручную, увидев, как вы уже проверили результат find:

std::string(search_text).substr ( 12, std::string( search_text ).find ("'", 13 )-1)
std::string("ABC_NAME = 'XYZSomeone' AND ABC_CLASS = 'XYZSomething'").substr ( 12, 22-1)

Теперь проверьте документацию для substr: "Возвращает подстроку [pos, pos + count)" .Символ в позиции 12 - это 'X' для части имени, а символ в позиции 12 + 21 = 33 - это 'L' для части класса.Таким образом, мы ожидаем, что подстрока начинается с этого 'X' и продолжается до этого 'L', то есть "XYZSomeone' AND ABC_C".Проверьте.

(Понятно, что можно забыть, занимает ли substr длину или позицию, на которой заканчивается. Разные языки с этим не согласны. Отсюда ссылка на документацию.)

Незатребованный комментарий

Попытка сделать так много в одной строке усложняет чтение и отладку кода.В этом случае это также ухудшает производительность.Нет необходимости преобразовывать search_text в std::string дважды.

std::string search_string{search_text};
std::size_t found = search_string.find('\'', 12);
if ( found != std::string::npos )
    found -= 12;
std::cout << search_string.substr(12, found) << std::endl;

Это сокращает число раз, когда строится строка (следовательно, время копирования данных строки), с трех до двух.

Если вы используете C ++ 17, вы можете еще больше повысить производительность, не создавая строки.Просто используйте std::string_view вместо std::string.Для этого сценария он имеет одинаковые функции-члены, принимающие одинаковые параметры;все, что вам нужно изменить, это тип search_string.Это ставит производительность в один ряд с кодом C.

Еще лучше: поскольку представления строк настолько дешевы в создании, вы можете даже написать свой код - без снижения производительности - так что не имеет значения, substr берет длину или занимает крайнюю конечную позицию.

std::string_view search_string{search_text};
std::string_view ltrimmed = search_string.substr(12);
std::size_t found = ltrimmed.find('\'');
std::cout << ltrimmed.substr(0, found) << std::endl;

Конструктивная лень FTW!

...