【问题标题】:C++ usage of strtok() on string字符串上 strtok() 的 C++ 用法
【发布时间】:2020-07-19 19:02:47
【问题描述】:

我从回答我之前的question 的人那里尝试了以下代码。

我的情况是我试图在这个字符串中获取值 1.2597,我的非功能性要求是使用 strtok 而不是 boost,这是许多其他编码人员在这里推荐的。

但是,我在将结果转换为可以使用 strtok 的 cstr* 时遇到问题。

我想知道如何获得 1.2597,并用strtok 回显它

string result= "CCY 1.2597 Down 0.0021(0.16%) 14:32 SGT [44]";

char *first = strtok(result, ' ');
char *second = strtok(0, ' ');

【问题讨论】:

  • strtok() 采用char*,而不是std::string(不要传递std::string::c_str(),因为strtok() 修改了提供的字符串)。请改用std::istringstream
  • 只需使用std::string.find(),就像您在问题中查找字符串一样。
  • 我的项目需要使用 strtok 来拆分字符串。
  • 我在下面尝试了很多示例,但仍然出现错误。我如何使用 strtok 获得 1.2597 字符串 result="CCY 1.2597 Down 0.0021(0.16%) 14:32 SGT [44]";

标签: c++


【解决方案1】:

您不能直接在 C++ std::string 上使用 strtok。它需要一个可变的以零结尾的 C 样式字符串,并且没有标准方法可以访问该形式的 std::string 的内容。

最简单的选择(不使用 Boost 或其他非标准库)是改用 C++ 流:

std::stringstream stream(result);
std::string first, second;
stream >> first >> second;

如果你想要的话,这也可以将第二个标记直接转换为数字类型。

如果您出于某种原因真的想使用strtok,那么一种可能性是将字符串复制到临时可变缓冲区中:

std::vector<char> temp(result.begin(), result.end());
temp.push_back(0);

char * first = strtok(&temp[0], ' ');
char * second = strtok(0, ' ');

注意strtok 的另一个主要错误:它不是线程安全的。

【讨论】:

    【解决方案2】:

    这行得通:

    std::string result= "CCY 1.2597 Down 0.0021(0.16%) 14:32 SGT [44]";
    size_t pos0 = result.find(' ');+1
    size_t pos1 = result.find(' ',pos0);
    std::string final_result = result.substr(pos0,pos1-pos0);
    

    【讨论】:

    • 您的代码确实有效,但我需要使用 strtok 函数进行拆分。
    • “分裂”是什么意思?
    【解决方案3】:

    是的,正如 Mike Seymore 所说,您必须将 std::string 复制到可变缓冲区。已经包含 string.h,只需使用 strcpy 将 std::string 复制到可变 char*。不要忘记为空终止包含空间+实际插入'\0';D

    std::string result = "...";
    char* token;
    char* buffer[res.length() + 1];  //Space for '\0'
    strcpy(buffer, result.c_str());
    buffer[res.length()] = '\0';     //insert '\0'
    token = strtok(buffer, " ");
    while (token != NULL) {
      /* work with token */
      token = strtok(NULL, " ");
    }
    

    【讨论】:

    • 这之后我如何获得令牌?
    • 在while循环中。如果你找到了你的令牌,只需使用“break”语句离开循环。 “token”现在包含您想要的令牌以供进一步工作。
    猜你喜欢
    • 1970-01-01
    • 2010-09-21
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多