2014-02-17 3 views
0

Я пишу программу на C++ для разбора фрагментов из веб-журналов, и одна из частей, которые я хочу, - это запрошенная страница. Я использую string::find для определения начала и конца страницы, затем используя string::substr, чтобы извлечь ее. Вот пример строки:Сбой со строкой :: find

172.138.80.174 - - [05/Aug/2001:21:06:27 -0300] "GET /~csc226 HTTP/1.0" 301 303 "http://www.goto.com/d/search/?Keywords=stringVar+%2B+savitch&view=2+80+0&did=" "Mozilla/4.61 [en] (Win98; I)" 

Запрашиваемая страница является частью сразу после GET, а конец находится прямо перед HTTP, поэтому я сделать что-то вроде:

int beginning = log_entry.find("\"GET") + 5; 
int end = log_entry.find("HTTP) - 5; 
std::string requested_page = log_entry.substr(beginning, end); 

Это то что будет содержаться в requested_page:

/~csc226 HTTP/1.0" 301 303 "http://www.goto.com/d/search/ 

Вместо

/~csc226 

Как вы можете видеть, начало правильное, но конца нет. У меня есть журнал из 3000 строк с тем же синтаксисом, что и пример, приведенный выше, и начало запрошенных страниц во всех из них является правильным, а концы - нет.

Любые идеи относительно того, что происходит не так?

Спасибо!

ответ

3

Не храните результат find в int. используйте std::string::size_type aka std::size_t.

Чтобы проверить, не удалось ли оно, сравните его с std::string::npos.

Во-вторых, никогда не манипулируйте результатом std::string::find, пока вы оба не подтвердите, что это не npos и знаете, что манипуляция перемещает его в пределах допустимого диапазона. +5 и -5 слепо - это не-go. Меня не волнует, знаете ли вы, что ваши данные. Не записывайте пропущенный код переполнения буфера.

И, наконец, substr(start, LENGTH) не substr(start, end).

std::string был импортирован из другой исходной библиотеки, чем стандартные контейнеры. Таким образом, его соглашения очень разные (и часто хуже).

+0

Хорошо, я должен был прочитать документацию заранее. Спасибо за четкое и краткое объяснение, именно то, что я искал! – user3026053

0
172.138.80.174 - - [05/Aug/2001:21:06:27 -0300] "GET /~csc226 HTTP/1.0" 301 303 "http://www.goto.com/d/search/?Keywords=stringVar+%2B+savitch&view=2+80+0&did=" "Mozilla/4.61 [en] (Win98; I)" 

Итак: log_entry.find("\"GET") + 5; будет соответствовать: "GET, а затем переместить итератор 5 мест вперед к месту:

172.138.80.174 - - [05/Aug/2001:21:06:27 -0300] "GET /~csc226 HTTP/1.0" 301 303 "http://www.goto.com/d/search/?Keywords=stringVar+%2B+savitch&view=2+80+0&did=" "Mozilla/4.61 [en] (Win98; I)" 
                ^

Следующая `log_entry.find ("HTTP"); будет соответствовать HTTP:

172.138.80.174 - - [05/Aug/2001:21:06:27 -0300] "GET /~csc226 HTTP/1.0" 301 303 "http://www.goto.com/d/search/?Keywords=stringVar+%2B+savitch&view=2+80+0&did=" "Mozilla/4.61 [en] (Win98; I)" 
                  ^

Вы хотите использовать (size_t length = log_entry.find("\"HTTP") - log_entry.find("\"GET") - 5;). Наконец, вам нужно правильно использовать std :: string :: substr here.

Смежные вопросы