c - 为什么 strtok 没有正确分隔该字符串? C

标签 c

  • riga_corrente 中的字符串是:"apelle figlio di apollo" .
  • d[0].stringa 的内容是“pelle”,compresso_s 的内容是“$11$”。
  • Temp 是一个 200 个字符的数组。

我想要"a$11$ figlio di apollo"里面riga_corrente但我只得到 "a$11$ fig"我不明白为什么。

我的部分代码:

strcpy(temp,strtok(riga_corrente,d[i].stringa));
strcat(temp,compresso_s);
strcat(temp,strtok(NULL,d[i].stringa));
strcpy(riga_corrente,temp);

最佳答案

这是您的问题,已转换为 MCVE ( Minimal, Complete, Verifiable Example ):

#include <stdio.h>
#include <string.h>

int main(void)
{
    char riga_corrente[200] = "apelle figlio di apollo";
    char stringa[] = "pelle";
    char compresso_s[] = "$11$";
    char temp[200];

    strcpy(temp, strtok(riga_corrente, stringa));
    strcat(temp, compresso_s);
    strcat(temp, strtok(NULL, stringa));
    strcpy(riga_corrente, temp);
    printf("[%s]\n", riga_corrente);

    return 0;
}

这会产生以下输出,这意味着库函数正在按设计工作(但显然不符合您的预期):

[a$11$ fig]

第一次调用strtok()停在 papelle ,用空字节替换它,并返回指向 a 的指针,复制到 temp 。然后附加 $11$来自compresso_s 。下次调用strtok()跳过e , l , leapelle并从空白处开始标记。字母f , i , g与分隔符不匹配,但是 l确实如此,所以 lfiglio被空字节破坏并返回指向空白的指针。该字符串已正确添加到 temp 的末尾,然后 temp覆盖riga_corrente因为strcpy() .

乍一看,您可以通过将第二次调用中的分隔符更改为strtok()来修复它。 ,也许只是一个换行符,甚至是一个空字符串。然而,剩下 elleapelle也作为输出的一部分。解决这个问题需要不同的技术——可能使用被低估的(并且鲜为人知的) strspn() strcspn() 自 1989 版以来标准 C 中已有的函数,或者可能使用 strstr() 查找字符串 pelle .

这不是很优雅(这里可能有一个函数试图逃脱),但这是有效的:

#include <stdio.h>
#include <string.h>

int main(void)
{
    char riga_corrente[200] = "apelle figlio di apollo";
    char stringa[] = "pelle";
    char compresso_s[] = "$11$";
    char temp[200];

    char *source = riga_corrente;
    char *p1 = strstr(source, stringa);
    if (p1 == NULL)
        strcpy(temp, source);
    else
    {
        *p1 = '\0';
        strcpy(temp, source);
        source = p1 + strlen(stringa);
    }
    strcat(temp, compresso_s);
    if (p1 != NULL)
    {
        p1 = strstr(source, stringa);
        if (p1 == NULL)
            strcat(temp, source);
        else
        {
            *p1 = '\0';
            strcat(temp, source);
        }
    }
    strcpy(riga_corrente, temp);
    printf("[%s]\n", riga_corrente);

    return 0;
}

这里没有缓冲区溢出保护等;通常不需要它,但原则上,如果 pelle从未出现在 riga_corrente ,您可能会遇到缓冲区溢出。

关于c - 为什么 strtok 没有正确分隔该字符串? C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52750077/

相关文章:

你能隐藏c中的文件吗?

c - 原地转置矩阵的函数

c - 读取子进程中的管道卡在第二次读取上

c++ - 如何将字符数转换为十进制数并返回或将 ASCII 'A' -'Z'/'a' -'z' 转换为字母偏移量 0 for 'A'/'a' ...?

编译时断言以确定指针是否为数组

在 C 中创建编号文件

python - 将数据数量/容量格式化为字符串

创建 C 子字符串 : looping with assignment operator VS strncopy, 哪个更好?

c - 使用 pthreads 读取临界区数据

c - 编译库与仅在应用程序中使用其源文件之间的区别