2012-05-28 132 views
3

我將字符串分割爲字符串C++串分割分割錯誤

vector<string> tokens; 

    stringstream strstm(str); 
    string item; 
    while (getline(strstm, item, ' ')) { 
     tokens.push_back(item); 
    } 

    token_idx = 0; 

    cout << "size = " << tokens.size() << endl; 

    for (unsigned int i = 0; i < tokens.size(); i++) 
    { 
     cout << tokens[i] << "[" << i << "]" << endl; 
    } 

的分化是成功的載體,和尺寸()和它的元素也是我喜歡它是。然而,當我試圖獲得它的價值時,最後一個令牌似乎行事異常。

string Lexer::consume() { 
    if (hasValue()) { 
     token_idx++; 
     cout << "consumed " << tokens[token_idx-1] << " tokens = " << token_idx -1 << endl; 
     return tokens[token_idx-1]; 
    } 
    cout << "didn't consume, token_idx = " << token_idx << endl; 
    return "null"; 
} 

hasVal是這樣

bool Lexer::hasValue() { 
    if (token_idx < tokens.size()) { 
     return true; 
    } else { 
     return false; 
    } 
} 

,如果我有一個輸入字符串像這樣1 + 2 * 3從我的節目預計輸出的應該是(+1(*23)),但我得到一個分段錯誤。

size = 5 
1[0] 
+[1] 
2[2] 
*[3] 
3[4] 
consumed 1 tokens = 0 
consumed + tokens = 1 
consumed 2 tokens = 2 
consumed * tokens = 3 
consumed 3 tokens = 4 
Segmentation fault (core dumped) 

但是,如果我改變了值檢查(token_idx < tokens.size() -1),程序將返回(+1 (*2 null))

size = 5 
1[0] 
+[1] 
2[2] 
*[3] 
3[4] 
consumed 1 tokens = 0 
consumed + tokens = 1 
consumed 2 tokens = 2 
consumed * tokens = 3 
didn't consume, token_idx = 4 
(+1 (*2 null)) 

所以我想知道如果分割方式時,有3個後線的終點,我是否還有一些其他因素會導致這種行爲?我相當肯定我不會超出界限。

+0

它在哪一行崩潰? –

+0

我在覈心轉儲文件上使用了gdb,但是它給我的信息非常含糊,並且不會告訴我它崩潰的代碼行。 使用命令'gdb prefixer core.3211'我得到 '核心是由'./prefixer'生成的。 程序以信號11結束,分段故障。 #0 0x0000003b1229c0d3 in std :: basic_string ,std :: allocator > :: size()const來自/usr/lib64/libstdc++.so.6 缺少單獨的debuginfos,請使用: debuginfo-install glibc-2.12-1.47.el6_2.12.x86_64 libgcc-4.4.6-3.el6.x86_64 libstdC++ - 4.4.6-3.el6.x86_64' –

+0

你用g ++編譯嗎?使用-g選項? –

回答

1

我認爲真正導致錯誤的代碼沒有顯示出來,但是因爲我可以感覺到你操作指針的方式......沒有任何隱瞞,你在訪問你的令牌列表的末尾時出錯,另外還有一個容易出錯的設計,就是這樣。

if (hasValue()) { // has value is useless to me 
    token_idx++; // why incrementing this here ? 

    cout << "consumed " << tokens[token_idx-1] << " tokens = " << token_idx -1 << endl; 

    return tokens[token_idx-1]; 
} 

它改成這樣:

if (token_idx < tokens.size()) { 
    cout << "consumed " << tokens[token_idx] << " tokens = " << token_idx << endl; 

    return tokens [ token_idx++ ]; 
} 

也瞭解recursive descent parsing,這是真的簡單,你將會有很多的分析更明智的,避免一些常見的陷阱。