遇到麻烦的字符串:: find

时间:2014-02-17 19:12:00

标签: c++ string find

我正在编写一个C ++程序来解析Web日志中的部分,我想要的其中一个部分就是所请求的页面。我正在使用string::find来定义页面的开头和结尾,然后使用string::substr来提取它。这是一个示例行:

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行的日志,其语法与上面的示例条目相同,并且所有页面中所请求页面的开头都是正确的,而结尾则不是。

关于出了什么问题的任何想法?

谢谢!

2 个答案:

答案 0 :(得分:3)

请勿将find的结果存储在int中。使用std::string::size_type又名std::size_t

要测试它是否失败,请与std::string::npos进行比较。

其次,永远不要操纵std::string::find的结果,直到你们都确认它不是npos并且知道操作将其移动到有效范围内。 +5-5盲目地是禁止的。我不在乎你是否“知道”你的数据是什么。不要写缓冲区溢出的有罪代码。

最后,substr( start, LENGTH )不是substr( start, end )

std::string是从与标准容器不同的源库导入的。所以它的惯例非常不同(通常更糟)。

答案 1 :(得分: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