使用 strtok 解析字符串 - 在 C++ 中两次
Posted
技术标签:
【中文标题】使用 strtok 解析字符串 - 在 C++ 中两次【英文标题】:parsing a string using strtok - twice in C++ 【发布时间】:2019-11-12 10:41:43 【问题描述】:我想使用 strtok 解析给定的字符串 - 但使用它两次。 要解析的字符串:“x=2;y=30”。 期望的输出: 一个包含 [x,y] 的字符串数组和一个包含 [2,30] 的字符串数组。 意思是,我想先用“;”作为分隔符,然后使用“=”作为分隔符。 我该怎么做 - 在 cpp 中?
【问题讨论】:
你好。向我们展示您的代码,看看您的阻塞点是什么 一定要使用strtok
吗? boost::string::split 或 std::regex 可能更容易
【参考方案1】:
在 C++ 中,我不会使用 std::strtok()
。 std::string
提供多种风格的 find
方法,例如std::string::find_first_of()
.
因为我忍不住要摆弄古老的strtok()
,所以一个小演示:
#include <cassert>
#include <cstring>
#include <iostream>
#include <vector>
int main()
char input[] = "x=2;y=30";
std::vector<char*> leftHandSides, rightHandSides;
for (char *in = input;;)
char *lhs = strtok(in, "=");
in = nullptr;
if (!lhs) break;
char *rhs = strtok(in, ";");
if (!rhs) break;
leftHandSides.push_back(lhs);
rightHandSides.push_back(rhs);
for (size_t i = 0, n = rightHandSides.size(); i < n; ++i)
std::cout << leftHandSides[i] << '=' << rightHandSides[i] << '\n';
输出:
x=2
y=30
Live Demo on coliru
注意事项:
strtok()
必须第一次使用指向缓冲区的指针(用于标记化)调用,并使用 0 指针来获取(相同缓冲区的)进一步结果。因此,char *in = input;
在char *lhs = strtok(in, "=");
之后被in = nullptr;
覆盖。在第一次迭代中完成这一点很重要。它也发生在所有其他迭代中是可以容忍的,因为它不会造成伤害。 (我本可以使用额外的 if
进行检查,但没有赢得任何东西。)
strtok()
修改输入字符串。因此,我有意使用了char input[] = "x=2;y=30";
。(使用const char *input = "x=2;y=30";
,我会使用U.B. 编写代码)
最后,使用std::istringstream
和std::getline()
代替std::strtok()
的变体:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
int main()
std::string input = "x=2;y=30";
std::vector<std::string> leftHandSides, rightHandSides;
for (std::istringstream in(input);;)
std::string lhs, rhs;
if (!std::getline(in, lhs, '=')
|| !std::getline(in, rhs, ';')) break;
leftHandSides.push_back(lhs);
rightHandSides.push_back(rhs);
for (size_t i = 0, n = rightHandSides.size(); i < n; ++i)
std::cout << leftHandSides[i] << '=' << rightHandSides[i] << '\n';
输出:
x=2
y=30
Live Demo on coliru
【讨论】:
第二个变体效果很好,关于 strtok(),你是对的。谢谢! @SarahDe-Paz 我的第一个反应是使用外部循环来分隔分配,使用内部循环来分隔 LHS 和 RHS。但后来我意识到,每次调用strtok()
都可以更改分隔符(即使对于相同的输入缓冲区也是如此)。 ;-)以上是关于使用 strtok 解析字符串 - 在 C++ 中两次的主要内容,如果未能解决你的问题,请参考以下文章