[英]Splitting a std::string into two const char*s resulting in the second const char* overwriting the first
我正在用空格分隔輸入行,並嘗試將數據讀取為兩個整數變量。
例如:“ 0 1”應該給child1 == 0
, child2 == 1
。
我使用的代碼如下:
int separator = input.find(' ');
const char* child1_str = input.substr(0, separator).c_str(); // Everything is as expected here.
const char* child2_str = input.substr(
separator+1, //Start with the next char after the separator
input.length()-(separator+1) // And work to the end of the input string.
).c_str(); // But now child1_str is showing the same location in memory as child2_str!
int child1 = atoi(child1_str);
int child2 = atoi(child2_str); // and thus are both of these getting assigned the integer '1'.
// do work
發生的事情使我困惑不已。 我正在使用Eclipse調試器(gdb)監視序列。 該函數啟動時, child1_str
和child2_str
顯示為具有不同的存儲位置(它們應該如此)。 分裂后的字符串separator
並獲得的第一個值, child1_str
持有“0”預期。
但是,下一行將值分配給child2_str
不僅將正確的值分配給child2_str
,還將覆蓋child1_str
。 我什至不意味着字符值將被覆蓋,我的意思是調試器顯示child1_str
和child2_str
共享內存中的相同位置。
什么啊
1)是的,我很樂意聽取其他將字符串轉換為int的建議-這是我很久以前就學會的方法,而且我從來沒有遇到過問題,因此不需要進行更改,但是:
2)即使有更好的方法來執行轉換,我仍然想知道這里發生了什么! 這是我的終極問題 。 因此,即使您提出了一種更好的算法,所選答案也將幫助我理解我的算法為何失敗。
3)是的,我知道std :: string是C ++,而const char *是標准C。atoi需要ac字符串。 我將其標記為C ++,因為輸入絕對來自我正在使用的框架中的std :: string。
首先,卓越的解決方案。
在C ++ 11中,您可以使用新的std::stoi
函數:
int child1 = std::stoi(input.substr(0, separator));
如果失敗,可以使用boost::lexical_cast
:
int child1 = boost::lexical_cast<int>(input.substr(0, separator));
現在,進行解釋。
input.substr(0, separator)
創建一個臨時的 std::string
對象, 該對象死於分號 。 在該臨時對象上調用c_str()
會給您一個指針,該指針僅在臨時生命存在時才有效。 這意味着,在下一行,指針已經無效。 取消引用該指針具有未定義的行為。 然后發生奇怪的事情,就像行為不確定的情況一樣。
銷毀字符串后, c_str()
返回的值無效。 因此,當您運行以下行時:
const char* child1_str = input.substr(0, separator).c_str();
substr
函數返回一個臨時字符串。 運行該行之后,該臨時字符串將被破壞,並且child1_str
指針變為無效。 訪問該指針將導致未定義的行為。
您應該做的是將substr
的結果分配給本地std::string
變量。 然后,您可以在該變量上調用c_str()
,結果將一直有效,直到銷毀該變量為止(在塊末尾)。
其他人已經指出了您當前代碼的問題。 這是我進行轉換的方法:
std::istringstream buffer(input);
buffer >> child1 >> child2;
更簡單,更直接,更不用說更加靈活了(例如,即使輸入在數字之間有一個制表符或兩個空格,它也將繼續起作用)。
input.substr
返回一個臨時的std::string
。 由於您沒有將其保存在任何地方,因此它將被銷毀。 之后發生的任何事情完全取決於您的運氣。
我建議使用istringstream
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.