2010-04-28 129 views
3

我想分割一個字符串使用空格作爲分隔符。我想將每個令牌存儲在一個數組或向量中。C++分割字符串

我試過了。

string tempInput; 
    cin >> tempInput; 
    string input[5]; 

    stringstream ss(tempInput); // Insert the string into a stream 
    int i=0; 
    while (ss >> tempInput){ 
     input[i] = tempInput; 
     i++; 
    } 

問題是,如果我輸入「這是一個測試」,數組似乎只存儲輸入[0] =「this」。它不包含輸入[2]到輸入[4]的值。

我也嘗試過使用矢量,但結果相同。

+0

不是一個真正的欺騙。這是「我在哪裏犯錯誤」vs「什麼是......的最佳方式」? – 2010-04-28 08:20:30

+0

雖然問題是完全一樣的:如何分割一個字符串,我相信@pmr提到的問題處理通用問題,而在這個問題中,問題不在於實際分裂 – 2010-04-28 08:21:28

+0

@David @SF是的,你是對的。不幸的是,大多數答案不會以這種方式處理問題。 – pmr 2010-04-28 08:29:53

回答

5

轉到重複問題以瞭解如何將字符串拆分爲單詞,但您的方法實際上是正確的。實際的問題在於你如何讀取輸入之前試圖分裂它:

string tempInput; 
cin >> tempInput; // !!! 

當您使用cin >> tempInput,你只從輸入,而不是整個文本獲得的第一個字。有工作你的出路是兩種可能的方式,其中最簡單的是忘掉了stringstream,並直接迭代輸入:

std::string tempInput; 
std::vector<std::string> tokens; 
while (std::cin >> tempInput) { 
    tokens.push_back(tempInput); 
} 
// alternatively, including algorithm and iterator headers: 
std::vector<std::string> tokens; 
std::copy(std::istream_iterator<std::string>(std::cin), 
      std::istream_iterator<std::string>(), 
      std::back_inserter(tokens)); 

這種方法會給你輸入的所有的標記在一個單一的矢量。如果您需要與各行的工作separatedly那麼你應該使用getline<string>頭,而不是cin >> tempInput

std::string tempInput; 
while (getline(std::cin, tempInput)) { // read line 
    // tokenize the line, possibly with your own code or 
    // any answer in the 'duplicate' question 
} 
3

注意,它更容易只是使用copy

vector<string> tokens; 
copy(istream_iterator<string>(cin), 
    istream_iterator<string>(), 
    back_inserter(tokens)); 

至於爲什麼您的代碼不起作用:你打算重用tempInput。不要這樣做。此外,您首先讀取的是cin,而不是的整個字符串。這就是爲什麼只有一個單詞被放入stringstream

1

最簡單的方法:Boost.Tokenizer

std::vector<std::string> tokens; 

std::string s = "This is, a test"; 
boost::tokenizer<> tok(s); 
for(boost::tokenizer<>::iterator it=tok.begin(); it != tok.end(); ++it) 
{ 
    tokens.push_back(*it); 
} 

// tokens is ["This", "is", "a", "test"] 

可以參數分隔符和逃避,如果你願意的話,默認情況下它記號化兩個空格和標點符號只需要空間序列。

+2

我希望人們會立即停止提升Boost作爲解決方案。許多地方,包括我現在(以前工作過的地方),在使用之前必須花費數月的時間審查許可和審計_any_開放源代碼項目,並且一般不值得痛苦和努力(更不用說等待)綠色(或紅色)燈。此外,如果這是一個家庭作業問題,那麼如果學生交出Boost謎語代碼,導師不會留下深刻的印象。 – 2010-04-28 08:25:34

+3

@ graham.reeds:很抱歉聽到,但 - 雖然運氣。 Boost是 - 最常用的**最合適的解決方案。你被允許使用標準庫嗎?畢竟,這是一個開放標準,其實現通常是開源的。無論如何,責怪你的公司,而不是提升或有幫助的答案。 :-( – 2010-04-28 08:29:21

+2

@ graham.reeds:另一種方法是隱藏可以在其他環境中使用的完全有效的答案?如果有人問如何在C++中解析XML,該怎麼辦?您想提供一個XML解析器的實現嗎?或者寧願將它引用到一個圖書館中去呢?在這種簡單的情況下,這個問題可能會同時得到純粹的C++和基於庫的解決方案,我相信,這樣做會增加價值,而不是把它拿走(注意:我沒有upvoted因爲我相信@Mike面臨的真正問題不是標記字符串,而是他如何讀取輸入) – 2010-04-28 08:35:27