【问题标题】:Passing the right argument to strtok将正确的参数传递给 strtok
【发布时间】:2020-04-16 09:05:23
【问题描述】:

我有这个字符串,我想用strtok() 分隔:

"+ 2 3\\nln 9\\ln 10"

然后我将 \\n 作为分隔符传递

    token = strtok(argv, "\\n");

    while (token)
    {
            args[index] = token;
            token = strtok(NULL, "\\n");
            index++;
    }

我的args 表中的第一个元素是+ 2 3,这很好,但是,第二个元素是l。 有谁明白为什么?如果是这样,我如何在我的args 表中获取我的ln 9

【问题讨论】:

  • 最后一个参数是可以作为分隔符的字符列表。所以"\\n" 表示你想在任何时候找到反斜杠或 n 时拆分它
  • 对不起,我编辑了字符串,结果与预期不同。我想在出现 \\n 的任何时候进行拆分,但它实际上执行了您刚才所说的操作
  • 您在找到反斜杠 '\' 或找到 'n' 字符的每个点分隔字符串。如果您希望它以换行符分隔您的字符串,请使用"\n" 作为字符串文字传递给strtok(3)

标签: c string strtok


【解决方案1】:

来自strtok() manpage

delim 参数指定一组字节,用于分隔 解析字符串中的标记。调用者可以指定不同的字符串 在解析相同字符串的连续调用中的 delim 中。

因此,在您的代码中,"\\n" 不是 完整字符串 分隔符。您只是对strtok 说分隔符是或者 '\'(因为双退格转义) 'n'

您的字符串标记"+ 2 3\\nln 9\\ln 10" 将是:

  1. "+ 2 3"
  2. \\ 之间的空字符串(strtok 不显示)
  3. \n 之间为空(strtok 不显示)
  4. "l"
  5. " 9"
  6. \\ 之间的空字符串(strtok 不显示)
  7. "l"
  8. " 10"

为了执行您正在尝试做的事情,strtok 不是最佳选择。我可能会编写自己的解析函数

  1. 使用strstr() 查找原始字符串中出现的"\\n"
  2. 将前一个字符串复制到某个输出字符串或 null 终止它

【讨论】:

  • 对不起,我的字符串是“+ 2 3\\nln 9\\ln 10”。我已经编辑了我的帖子
  • @Avocado 这不会改变分析。您将有多个空字符串,而不是一个。
  • 那我怎么告诉strtok分隔符是\\n呢?
  • @Avocado 你不能。它只接受一组单个字符分隔符。
  • 试试这个stackoverflow.com/questions/29788983/… 还有这个:stackoverflow.com/questions/34942523/… 但忽略完全错误的已接受答案 - 其他答案可能对你有用。
【解决方案2】:

我完全同意 Roberto 和 Gerhardh 的上述回答和建议。

如果您对多分隔符的 strtok 自定义实现感到满意,您可以使用以下工作解决方案。

char *strtokm(char *str, const char *delim)
{
    static char *tok;
    static char *next;
    char *m;

    if (delim == NULL) return NULL;

    tok = (str) ? str : next;
    if (tok == NULL) return NULL;

    m = strstr(tok, delim);

    if (m) {
        next = m + strlen(delim);
        *m = '\0';
    } else {
        next = NULL;
    }

    return tok;
}

【讨论】:

  • 感谢您的示例。那么理论上,如果你使用 strpbrk 而不是 strstr,这将与 strtok 相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-07
  • 2016-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多