【问题标题】:c++ tokenize std string [duplicate]c ++标记std字符串[重复]
【发布时间】:2012-09-19 14:04:04
【问题描述】:

可能重复:
How do I tokenize a string in C++?

您好,我想知道如何使用 strtok 标记 std 字符串

string line = "hello, world, bye";    
char * pch = strtok(line.c_str(),",");

我收到以下错误

error: invalid conversion from ‘const char*’ to ‘char*’
error: initializing argument 1 of ‘char* strtok(char*, const char*)’

我正在寻找一种快速简便的方法,因为我认为这不需要太多时间

【问题讨论】:

  • 我以前见过这种问题。可能重复。

标签: c++ tokenize strtok


【解决方案1】:
std::string::size_type pos = line.find_first_of(',');
std::string token = line.substr(0, pos);

要查找下一个令牌,请重复 find_first_of,但从 pos + 1 开始。

【讨论】:

  • 有了这个,就必须有另一个变量来跟踪 pos1 和 pos2。否则,您将使用从 0 到新 pos 的子字符串,而不是 pos1 到 pos2。
【解决方案2】:

您可以通过执行&*line.begin() 来使用strtok 来获取指向char 缓冲区的非常量指针。我通常更喜欢在 C++ 中使用 boost::algorithm::split

【讨论】:

  • 我认为通过丢弃字符串内部指针上的 const,您允许 strtok 修改字符串的内部指针 - 非常脏。
  • 这是个糟糕的主意。它会将std::string 置于未定义状态。您不应该使用 C 字符串函数修改 std::string
  • @japreiss 它怎么可能出错?通过它的迭代器修改字符串中的字符并没有错,C++字符串是always contiguous in practice,在C++11中保证是连续的并且以null结尾。
  • @spencercw:不保证字符串的内部表示是零终止的;它可能使用写时复制语义,在这种情况下颠覆const 可能会更改字符串的其他副本。可能(或不可能)证明您所做的事情对于任何符合要求的实现都是明确定义的,但即使可以,我也不希望像这样测试符合性的边缘情况。
  • @MikeSeymour 内部缓冲区在 C++11 (see this answer) 中保证为空终止。不过,您通过写时复制提出了一个有趣的观点。我猜想在这样的实现中,取消引用迭代器会触发复制,或者当strtok 写入缓冲区时,某种内存保护会触发复制。有没有真正做 CoW 的实现?
【解决方案3】:

strtok 是一个相当古怪、邪恶的函数,它修改了它的参数。这意味着您不能直接在 std::string 的内容上使用它,因为无法从该类中获取指向可变的、以零结尾的字符数组的指针。

您可以处理字符串数据的副本:

std::vector<char> buffer(line.c_str(), line.c_str()+line.size()+1);
char * pch = strtok(&buffer[0], ",");

或者,对于更多的 C++ 习惯用法,您可以使用字符串流:

std::stringstream ss(line);
std::string token;
std::readline(ss, token, ',');

或者更直接地找到逗号:

std::string token(line, 0, line.find(','));

【讨论】:

    【解决方案4】:

    我总是将getline 用于此类任务。

    istringstream is(line);
    string part;
    while (getline(is, part, ','))
      cout << part << endl;
    

    【讨论】:

      猜你喜欢
      • 2012-11-11
      • 1970-01-01
      • 1970-01-01
      • 2012-04-20
      • 1970-01-01
      • 1970-01-01
      • 2021-08-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多