2011-05-04 147 views
27

可能重複:
How to split a string in C++?分割字符串用一個空格

我需要用一個空格分割字符串,並將其存儲到字符串數組。我可以使用istringstream實現這一點,但我無法實現的是:

我希望每個空間都可以終止當前單詞。所以,如果連續有兩個空格,我的數組中的一個元素應該是空白的。

例如:

(下劃線表示空格)

This_is_a_string. 
gets split into: 
A[0] = This 
A[1] = is 
A[2] = a 
A[3] = string. 

This__is_a_string. 
gets split into: 
A[0] = This 
A[1] = "" 
A[2] = is 
A[3] = a 
A[4] = string. 

我如何能實現呢?

回答

20

你甚至可以開發自己的分割功能(我知道,有點老套):

unsigned int split(const std::string &txt, std::vector<std::string> &strs, char ch) 
{ 
    unsigned int pos = txt.find(ch); 
    unsigned int initialPos = 0; 
    strs.clear(); 

    // Decompose statement 
    while(pos != std::string::npos) { 
     strs.push_back(txt.substr(initialPos, pos - initialPos + 1)); 
     initialPos = pos + 1; 

     pos = txt.find(ch, initialPos); 
    } 

    // Add the last one 
    strs.push_back(txt.substr(initialPos, std::min(pos, txt.size()) - initialPos + 1)); 

    return strs.size(); 
} 

然後你只需要一個載體<字符串來調用它>作爲參數:

int main() 
{ 
    std::vector<std::string> v; 

    split("This is a test", v, ' '); 
    show(v); 

    return 0; 
} 
+0

警告! :)如果你想要沒有空格的元素,只需將「 - initialPos + 1」替換爲「 - initialPos」 – teejay 2013-10-17 15:06:42

2

如果你不反對提高,boost.tokenizer具有足夠的靈活性來解決這個

#include <string> 
#include <iostream> 
#include <boost/tokenizer.hpp> 

void split_and_show(const std::string s) 
{ 
    boost::char_separator<char> sep(" ", "", boost::keep_empty_tokens); 
    boost::tokenizer<boost::char_separator<char> > tok(s, sep); 
    for(auto i = tok.begin(); i!=tok.end(); ++i) 
      std::cout << '"' << *i << "\"\n"; 
} 
int main() 
{ 
    split_and_show("This is a string"); 
    split_and_show("This is a string"); 

} 

測試:https://ideone.com/mN2sR

4

你可以使用boost

samm$ cat split.cc 
#include <boost/algorithm/string/classification.hpp> 
#include <boost/algorithm/string/split.hpp> 

#include <boost/foreach.hpp> 

#include <iostream> 
#include <string> 
#include <vector> 

int 
main() 
{ 
    std::string split_me("hello world how are you"); 

    typedef std::vector<std::string> Tokens; 
    Tokens tokens; 
    boost::split(tokens, split_me, boost::is_any_of(" ")); 

    std::cout << tokens.size() << " tokens" << std::endl; 
    BOOST_FOREACH(const std::string& i, tokens) { 
     std::cout << "'" << i << "'" << std::endl; 
    } 
} 

樣品執行:

samm$ ./a.out 
8 tokens 
'hello' 
'world' 
'' 
'how' 
'are' 
'' 
'' 
'you' 
samm$ 
+0

這有更好的可讀性 – 2014-01-27 06:49:36

3

如果你厭惡的提振,你可以使用普通的舊operator>>,用std::noskipws一起:

編輯:測試後更新。

#include <iostream> 
#include <iomanip> 
#include <vector> 
#include <string> 
#include <algorithm> 
#include <iterator> 
#include <sstream> 

void split(const std::string& str, std::vector<std::string>& v) { 
    std::stringstream ss(str); 
    ss >> std::noskipws; 
    std::string field; 
    char ws_delim; 
    while(1) { 
    if(ss >> field) 
     v.push_back(field); 
    else if (ss.eof()) 
     break; 
    else 
     v.push_back(std::string()); 
    ss.clear(); 
    ss >> ws_delim; 
    } 
} 

int main() { 
    std::vector<std::string> v; 
    split("hello world how are you", v); 
    std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, "-")); 
    std::cout << "\n"; 
} 

http://ideone.com/62McC

0

你可以使用簡單的strtok()函數(*)From here。該令牌上的分隔符創建注

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    char str[] ="- This is a string"; 
    char * pch; 
    printf ("Splitting string \"%s\" into tokens:\n",str); 
    pch = strtok (str," ,.-"); 
    while (pch != NULL) 
    { 
    printf ("%s\n",pch); 
    pch = strtok (NULL, " ,.-"); 
    } 
    return 0; 
} 
1

你也可以只使用舊的時尚「的strtok」

http://www.cplusplus.com/reference/clibrary/cstring/strtok/

它有點靠不住的,但使用升壓不涉及(不,是提振一件壞事)。

你基本上用你想分割的字符串和分隔符(在這種情況下是一個空格)調用strtok,它會返回一個char *。

從鏈接:

​​
19

如果嚴格一個空格字符是分隔符, 可能std::getline將是有效的。
例如:

int main() { 
    using namespace std; 
    istringstream iss("This is a string"); 
    string s; 
    while (getline(iss, s, ' ')) { 
    printf("`%s'\n", s.c_str()); 
    } 
} 
+2

任何人都可以解釋性能開銷 '字符串行,單詞;同時(getline(cin,line))istringstream ss(line); while(ss >> word) //解析字 }' 具體來說,字符串istringstream構造函數是如何實現的,它是否複製字符串?編譯器是否足夠聰明以將ss聲明移出while循環? 謝謝 – csyangchen 2012-06-09 12:41:17

+0

很簡單的實現。謝謝! – 2017-11-17 04:59:41