我正在使用以下内容,但不确定如何在其中包含分隔符。
void Tokenize(const string str, vector<string>& tokens, const string& delimiters)
{
int startpos = 0;
int pos = str.find_first_of(delimiters, startpos);
string strTemp;
while (string::npos != pos || string::npos != startpos)
{
strTemp = str.substr(startpos, pos - startpos);
tokens.push_back(strTemp.substr(0, strTemp.length()));
startpos = str.find_first_not_of(delimiters, pos);
pos = str.find_first_of(delimiters, startpos);
}
}
答案 0 :(得分:17)
C++ String Toolkit Library (StrTk)有以下解决方案:
std::string str = "abc,123 xyz";
std::vector<std::string> token_list;
strtk::split(";., ",
str,
strtk::range_to_type_back_inserter(token_list),
strtk::include_delimiters);
它应该导致token_list具有以下元素:
Token0 = "abc," Token1 = "123 " Token2 = "xyz"
可以找到更多示例Here
答案 1 :(得分:4)
我现在这有点草率,但这就是我最终的结果。我不想使用boost,因为这是一项学校作业,我的导师希望我使用find_first_of来实现这一目标。
感谢大家的帮助。
vector<string> Tokenize(const string& strInput, const string& strDelims)
{
vector<string> vS;
string strOne = strInput;
string delimiters = strDelims;
int startpos = 0;
int pos = strOne.find_first_of(delimiters, startpos);
while (string::npos != pos || string::npos != startpos)
{
if(strOne.substr(startpos, pos - startpos) != "")
vS.push_back(strOne.substr(startpos, pos - startpos));
// if delimiter is a new line (\n) then addt new line
if(strOne.substr(pos, 1) == "\n")
vS.push_back("\\n");
// else if the delimiter is not a space
else if (strOne.substr(pos, 1) != " ")
vS.push_back(strOne.substr(pos, 1));
if( string::npos == strOne.find_first_not_of(delimiters, pos) )
startpos = strOne.find_first_not_of(delimiters, pos);
else
startpos = pos + 1;
pos = strOne.find_first_of(delimiters, startpos);
}
return vS;
}
答案 2 :(得分:2)
我无法真正遵循您的代码,您是否可以发布有效的程序?
无论如何,这是一个简单的标记化器,没有测试边缘情况:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void tokenize(vector<string>& tokens, const string& text, const string& del)
{
string::size_type startpos = 0,
currentpos = text.find(del, startpos);
do
{
tokens.push_back(text.substr(startpos, currentpos-startpos+del.size()));
startpos = currentpos + del.size();
currentpos = text.find(del, startpos);
} while(currentpos != string::npos);
tokens.push_back(text.substr(startpos, currentpos-startpos+del.size()));
}
示例输入,分隔符= $$
:
Hello$$Stack$$Over$$$Flow$$$$!
令牌:
Hello$$
Stack$$
Over$$
$Flow$$
$$
!
注意:我绝不会使用我在没有测试的情况下编写的标记器!请使用boost::tokenizer!
答案 3 :(得分:2)
如果分隔符是字符而不是字符串,则可以使用strtok。
答案 4 :(得分:0)
这取决于您是否需要前面的分隔符,以下分隔符或两者,以及您希望在字符串的开头和结尾处使用字符串,这些字符串可能在它们之前/之后没有分隔符。
我假设你想要每个单词,前面和后面的分隔符,但不是任何分隔符串(例如,如果在最后一个字符串后面有分隔符)。
template <class iter>
void tokenize(std::string const &str, std::string const &delims, iter out) {
int pos = 0;
do {
int beg_word = str.find_first_not_of(delims, pos);
if (beg_word == std::string::npos)
break;
int end_word = str.find_first_of(delims, beg_word);
int beg_next_word = str.find_first_not_of(delims, end_word);
*out++ = std::string(str, pos, beg_next_word-pos);
pos = end_word;
} while (pos != std::string::npos);
}
目前,我把它写成更像STL算法,为其输出采用迭代器,而不是假设它总是推送到集合上。由于它在输入中依赖(暂时)是一个字符串,因此它不会使用迭代器作为输入。