2014-02-17 96 views
0

我正在編寫一個C++程序來解析網絡日誌中的碎片,而我想要的碎片之一就是請求的頁面。我使用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行的日誌,其語法與上面的示例條目相同,並且所有請求頁面的開頭部分都是正確的,而結尾部分不是。

任何有關錯誤的想法?

謝謝!

回答

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從不同於標準容器的源庫導入。所以它的慣例是非常不同的(並且往往更糟糕)。

+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