【问题标题】:skip strtok's null terminators safely安全地跳过 strtok 的空终止符
【发布时间】:2020-07-30 09:37:48
【问题描述】:

我想使用strtok,然后在strtok放置的空终止符之后返回字符串。

char *foo(char *bar)
{
strtok(bar, " ");
return after_strtok_null(bar);
}
/*
examples:
foo("hello world") = "world"
foo("remove only the first") = "only the first"
*/

我的代码 不是 用于跳过第一个单词(我知道一个简单的 while 循环会做)但我确实想使用一次 strtok 然后返回不是的部分标记化。

我将在问题的最后提供我正在尝试做的事情的详细信息,尽管我认为这不是真的必要

我想到的一个解决方案是简单地跳过所有空终止符,直到我到达一个非空:

char *foo(char *bar)
{
bar = strtok(bar, " ");
while(!(*(bar++)));
return bar;
}

这适用于上面显示的示例,但在单个单词上使用它时 - 我可能会错误地将字符串的空终止符识别为 strtok 的空终止符,然后我可能会访问未分配的内存。

例如,如果我尝试foo("demo"\* '\0' *\),那么strtok 将是"demo"\* '\0' *\ 然后,如果我运行while 循环,我将指责字符串demo 之后的部分。我尝试过的另一种解决方案是使用strlen,但这个有完全相同的问题。

我正在尝试创建一个获取句子的函数。有些句子的第一个单词以冒号结尾,尽管不一定。如果函数以冒号结尾,则该函数需要获取第一个单词并将其(不带冒号)插入到某个全局表中。然后返回没有第一个冒号的句子 - 终止的单词,如果单词有冒号,则返回单词后面没有空格 - 开头的单词终止,否则,只返回句子开头没有空格的句子。

【问题讨论】:

标签: c string strtok ansi-c null-terminated


【解决方案1】:

您可以改用str[c]spn

char *foo(char *bar) {
    size_t pos = strcspn(bar, " ");
    pos = strspn((bar += pos), "");
    // *bar = '\0';   // uncomment to mimic strtok
    return bar + pos;
}

你会得到一个空字符串的预期子字符串。

一个好处是您可以避免更改原始字符串 - 即使模仿 strtok 是微不足道的......

【讨论】:

    猜你喜欢
    • 2019-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多