27 12月 2007

[C/C++] string使用strtok的問題

string ip1 = "140.113.100.1";
string ip2 = ip1;
strtok( (char*)ip1.c_str(), "." );
cout<<ip1<<endl;
cout<<ip1<<endl;

這樣子的結果,會讓ip1與ip2的內容變成一樣的!!! 為什麼呢? 這一切都是strtok的陰謀啦!!!

首先 先了解一下strtok的處理動作:
char * strtok( char * input, const char * delimiter);
每呼叫一次,便將input裡的第一個delimiter字元,改成'\0' (內碼為0)。因為strtok會將input的字串的內容值改掉,因為當input=="140.113.100.1",呼叫strtok一次後,會變成"140\0113.100.1",呼叫三次後,會變成"140\0113\0100\01"。

所以在呼叫strtok時,自以為小聰明的把原本strtok(ip1.c_str(),".");產生的error改掉。改成strtok((char*)ip1.c_str(),".");將ip1.c_str()的型別const char *強制轉換成char *,才會產生這種結果。產生error的時候,就是在提醒你,可能會有問題囉。


再來,明明ip1與ip2是不一樣的變數,怎麼改到ip1後,ip2也變了呢!?
這邊的話,就跟string的assignment function的機制有關係了,據我測試後的猜測,應該是當ip2=ip1;時,兩個的字串的指標是指到同一塊memory的(for 效率)。而當ip1或ip2其中任一個將字串裡的值改變後,string的assignment function才會再allocate另一塊memory給改變字串值的變數使用。

因此,上面的code的結果,才會讓ip1與ip2的印出的結果是一樣。
所以,結論就是,想要對c++的string切token的話,就不要用c的strtok()!!!

沒有留言: