2010-04-28 128 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