2011-05-04 150 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