现在我已经设置了代码来将我的字符串分成带有分隔符的标记:; =和空格。我还想将特殊字符作为标记包含在内。
char * cstr = new char [str.length()+1];
strcpy (cstr, str.c_str());
char * p = strtok (cstr," ");
while (p!=0)
{
whichType(p);
p = strtok(NULL," ,;=");
}
所以现在如果我打印出一个字符串的标记,例如,asd sdf qwe wer,sdf;wer
它将是
asd
sdf
qwe
wer
sdf
wer
我希望它看起来像
asd
sdf
qwe
wer
,
sdf
;
wer
任何帮助都会很棒。感谢
答案 0 :(得分:10)
您需要更多灵活性。 (此外,strtok
是一个错误的,容易出错的界面)。
这是一个灵活的算法,可以生成令牌,将它们复制到输出迭代器。这意味着您可以使用它来填充您选择的容器,或者将其直接打印到输出流(我将用作演示)。
行为在选项标志中指定:
enum tokenize_options
{
tokenize_skip_empty_tokens = 1 << 0,
tokenize_include_delimiters = 1 << 1,
tokenize_exclude_whitespace_delimiters = 1 << 2,
//
tokenize_options_none = 0,
tokenize_default_options = tokenize_skip_empty_tokens
| tokenize_exclude_whitespace_delimiters
| tokenize_include_delimiters,
};
并非如何实际提取您未命名的额外要求,但您的示例暗示:您希望分隔符输出为标记 除非 ,否则它们是空格(' '
)。这就是第三个选项:tokenize_exclude_whitespace_delimiters
。
现在这是真正的肉:
template <typename Input, typename Delimiters, typename Out>
Out tokenize(
Input const& input,
Delimiters const& delim,
Out out,
tokenize_options options = tokenize_default_options
)
{
// decode option flags
const bool includeDelim = options & tokenize_include_delimiters;
const bool excludeWsDelim = options & tokenize_exclude_whitespace_delimiters;
const bool skipEmpty = options & tokenize_skip_empty_tokens;
using namespace std;
string accum;
for(auto it = begin(input), last = end(input); it != last; ++it)
{
if (find(begin(delim), end(delim), *it) == end(delim))
{
accum += *it;
}
else
{
// output the token
if (!(skipEmpty && accum.empty()))
*out++ = accum; // optionally skip if `accum.empty()`?
// output the delimiter
bool isWhitespace = std::isspace(*it) || (*it == '\0');
if (includeDelim && !(excludeWsDelim && isWhitespace))
{
*out++ = { *it }; // dump the delimiter as a separate token
}
accum.clear();
}
}
if (!accum.empty())
*out++ = accum;
return out;
}
完整演示 Live on Ideone (default options) 和 Live on Coliru (no options)
int main()
{
// let's print tokens to stdout
std::ostringstream oss;
std::ostream_iterator<std::string> out(oss, "\n");
tokenize("asd sdf qwe wer,sdf;wer", " ;,", out/*, tokenize_options_none*/);
std::cout << oss.str();
// that's all, folks
}
打印:
asd
sdf
qwe
wer
,
sdf
;
wer
答案 1 :(得分:4)
我担心你不能使用strtok
,你需要一个合适的标记器。
如果您的令牌很简单,我建议您手动编码,即逐字符扫描字符串。如果他们不是,我建议你看看several alternatives。或者,如果它真的很复杂,那么您使用的是flex
等特殊工具。
答案 2 :(得分:-1)
//TRY THE FOLLOWING CODE
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::string line = "asd sdf qwe wer,sdf;wer";
std::vector<std::string> wordVector;
std::vector<std::string>::iterator IwordVector;
std::size_t prev = 0, pos;
while ((pos = line.find_first_of(" ,;", prev)) != std::string::npos) {
if (pos > prev)
wordVector.push_back(line.substr(prev, pos-prev));
prev = pos+1;
if (std::string(1,line.at((unsigned int)pos)) != " ")
wordVector.push_back(std::string(1,line.at((unsigned int)pos)));
}
if (prev < line.length())
wordVector.push_back(line.substr(prev, std::string::npos));
for(IwordVector = wordVector.begin(); IwordVector != wordVector.end(); IwordVector++)
std::cout << "\n"<<*IwordVector;
return 0;
}
**OUPUT**: [root@kumar-vm ~]# ./a.out
asd
sdf
qwe
wer
,
sdf
;
wer[root@kumar-vm ~]#