Strtok 如何也包含分隔符作为令牌
strtok how to also include delimiters as tokens
现在我已经设置了代码,将我的字符串分成带有分隔符的标记,;= 和空格。我还想包含特殊字符作为令牌。
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
任何帮助都会很棒。谢谢
您需要更大的灵活性。(此外,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 == ' ');
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(默认选项)和Live on Coliru(无选项)
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
恐
怕你不能为此使用strtok
,你需要一个合适的分词器。
如果您的令牌很简单,我建议您手动编码,即逐个字符扫描字符串。 如果不是,我建议你看看几种选择。 或者,如果它真的很复杂,您可以使用像 flex
.
//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 ~]#
相关文章:
- 如何在C++中使用X509证书模在令牌中查找私钥
- holeMenuProgram.cpp:38:1 错误:'}'令牌之前的预期主表达式
- C++:"("令牌"之前有预期的非限定 id 指向类中成员函数的指针
- Arduino 用于语句错误。令牌之前的预期')' ';'。如何解决这个问题?
- 错误:令牌 { '{' 之前应存在非限定 ID
- 允许哪些令牌作为 #include 的参数?
- "错误 C0000:语法错误,令牌"<EOF>"处出现意外$end,并且不确定
- 它在 { 令牌之前给了我预期的标识符
- (错误:令牌之前'<<'预期的主表达式)
- 为什么 ## aka 令牌粘贴运算符不适用于 C 和 C++ 中的注释?
- 错误:"->"令牌之前的预期初始值设定项
- LINUX 操作系统上的错误:令牌之前预期的构造函数、析构函数或类型转换'('?
- 丢失读入的每一行输入中的最后一个令牌
- 如何使用 libCurl 将访问令牌发送到服务器 API
- C++令牌定义成员
- 宏定义中的预处理器令牌两边有两个双引号
- 如何将C++输入流分隔符包含在结果令牌中
- Boost.Tokenizer如何不从令牌中删除分隔符
- Strtok 如何也包含分隔符作为令牌
- boost::tokenizer来考虑分隔符之间是否缺少令牌