我正在编写一个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行的日志,其语法与上面的示例条目相同,并且所有页面中所请求页面的开头都是正确的,而结尾则不是。
关于出了什么问题的任何想法?
谢谢!
答案 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。