Повысить find_first как это работает?/ Определить диапазон - PullRequest
5 голосов
/ 20 февраля 2012

У меня есть буфер (например, char buffer[1024]), который заполняется некоторыми данными.Теперь я хочу найти подстроку в этом буфере.Так как это должен быть поиск без учета регистра, я использую boost::algorithm::ifind_first.

Поэтому я вызываю функцию следующим образом:

boost::iterator_range<char*> buf_iterator;
buf_iterator = boost::algorithm::ifind_first(buffer ,"substring");

Это на самом деле работает нормально.Но меня беспокоит следующее:

Я передаю функцию просто как char pointer, поэтому ifind_first не должен знать, где заканчивается мой буфер, но он все еще работает, хотя.

Теперь мойПервой идеей было то, что функция выполняет поиск до символа завершения строки.Но в Boost Documentation функция определяется следующим образом:

template<typename Range1T, typename Range2T> 
  iterator_range< typename range_iterator< Range1T >::type > 
  find_first(Range1T & Input, const Range2T & Search);

Поскольку она работает с параметрами шаблона, я на самом деле сомневаюсь, что она работает с нулевым завершением?

Итак, мой вопрос: как ifind_first знает, где остановиться?Или, если быть более точным, как я могу дать ему диапазон?Как уже упоминалось, он отлично работает с char*, но я не совсем уверен, что мне просто не повезло - я имею в виду, что в худшем случае функция вызывается и не знает, где остановиться и войти в неопределенную память...

Редактировать:

Теперь в ответе упоминалось, что это зависит от типа, который я передаю функции.Теперь это будет означать, что если я работаю с буфером char, я всегда должен быть уверен, что он заканчивается 0 ...?

1 Ответ

5 голосов
/ 20 февраля 2012

Используется метод, в котором длина массива является аргументом шаблона, то есть:

template< typename T, size_t L >
void foo( T (&arr)[L] )
{
}

Поскольку строковый литерал имеет известную длину L, его можно вывести, например, foo ("test"), являющийся foo (). Могу поспорить, что есть перегрузка для const char *, где предполагается, что аргумент является c-строкой, где strlen () может использоваться для определения длины.

РЕДАКТИРОВАТЬ: Лучшее объяснение того, как ifind_first потерпит неудачу и почему не будет, если вы будете осторожны

Что решит, будет ли ifind_first провален или нет в этом случае, так это то, превратится ли тема или поиск в символ *. В этом случае вы передали строковый литерал в качестве непосредственного поиска, ifind_first попытается и предположит, что это const char [10] (длина "substring" + 1 для терминатора NULL). Однако для поиска это не имеет значения, потому что даже если он выродится в const char *, ifind_first будет догадываться, что это строка c с нулевым символом в конце, а строковый литерал является строкой c с нулевым символом в конце, поэтому он работает.

В этом случае вы действительно запрашиваете буфер символов [1024], в вашем случае он не вырождается в символ *. Но если бы вместо этого у вас было бы, скажем, char * buffer = new char [1024]; тип буфера - char *, и он не гарантированно завершается NULL. В этом случае ifind_first завершится сбоем таинственным образом, в зависимости от того, что находится после заполненной области.

Итак, в заключение, поскольку тип буфера char [1024], в вашем случае он не будет касаться памяти за концом буфера, НО, он также не будет заботиться о том, есть ли в нем терминатор NULL (он не не ищите его, поскольку вы передали ему символ [1024], который знает длину во время компиляции). Так что, если, скажем, вы заполнили буфер 12 символами, за которыми следует NULL, он все равно будет искать весь буфер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...