2012-11-06 87 views
0

嗨即時做字符串標記化類似於下面的例子。然而,在while循環中,例如,我將改變字母'a'爲'hellow'。在分配myVar [i]之前嘗試更改pch時,出現分段錯誤。我該如何去做呢?strtok字符串和修改令牌值

map <int, char*> myVar; 
    char str[] ="- This, a sample string."; 
    char * pch; 
    printf ("Splitting string \"%s\" into tokens:\n",str); 
    pch = strtok (str," ,.-"); 
    int i = 0; 

    while (pch != NULL) 
    { 
     printf ("%s\n",pch); 

     //modify token value 
     stringstream strStream; 
     strStream << "hello_world"; 

     char newStr[7] = {0}; 
     memcpy(newStr, strStream, 7); 

     myVar[i] = (char*)newStr; 
     pch = strtok (NULL, " ,.-"); 
     i++; 
    } 
+2

你的意思是 「改變PCH」? – Gian

+4

您發佈的代碼不是您遇到問題的代碼(對令牌沒有任何更改)。發佈*不*工作的代碼。 –

+0

嘿抱歉,我已經編輯了上面的代碼。 – nuttynibbles

回答

2

我看到你的while環內的兩個錯誤:

1)要傳遞的stringstream本身,而不是數據它包含,以memcpy()。您正在依靠stringstream::operator void*()轉換運算符。你不應該尊重那個指針,因爲它並不指向實際的數據。這只是一個標誌,表明stringstream是否有效。要將stringstream數據傳遞給memcpy(),您必須首先調用其str()方法以獲取包含數據的std::string,然後調用其c_str()方法將該數據傳遞給memcpy()。 2)當您將值插入std::map時,您每次插入一個本地char[]變量。該char[]之後立即超出範圍,使std::map包含指向堆棧中隨機位置的指針。根據您所顯示的代碼,char[]緩衝區每次都可能重複使用相同的堆棧空間。

由於您使用C++,你真的應該使用更多的C++ - 面向的東西,比如std::stringstd::cout

試試這個:

std::map <int, std::string> myVar; 
std::string str = "- This, a sample string."; 
std::cout << "Splitting string \"" << str << "\" into tokens:" << std::endl; 
size_t start = 0; 
int i = 0; 

do 
{ 
    std::string token; 

    size_t pos = str.find_first_of(" ,.-", start); 
    if (pos != std::string::npos) 
    { 
     token = str.substr(start, pos-start); 
     start = pos + 1; 
    } 
    else 
    { 
     token = str.substr(start); 
     start = std::string::npos; 
    } 

    std::cout << token << std::endl; 

    //modify token value 
    myVar[i] = "hello_world"; 

    ++i; 
} 
while (start != std::string::npos); 
+0

是不是修改std :: string.c_str()的返回值的no-no? (正如strtok所做的那樣) – enhzflep

+0

這是一個禁止修改由c_str()返回的值的方法。它清楚地寫在文檔中。引用http://www.cplusplus.com/reference/string/string/c_str/:「返回的數組指向一個內部位置,該位置具有此字符序列所需的存儲空間及其終止空字符,但值這個數組不應該在程序中修改,只有在下一次調用字符串對象的非常量成員函數時才保證不變。「對於C++方式的建議+1,錯誤-1。結果0. – enhzflep

+0

那麼,我說是應該替換'strtok()',畢竟。這將消除「修改c_str()」問題... –

0

你看,事情是:strtok的修改傳遞給它的字符串。 如果您嘗試在字符串常量上使用它,通常會出現段錯誤,因爲內存不是真的需要更改。

我用來解決這個問題的方法是始終在字符串的重複上使用strtok。

char *srcStr = "Some constant text"; 
char *tmpStr = strdup(srcStr); 
//... 
//some operations involving strtok 
//... 
free(tmpStr);