繁体   English   中英

使用 strtok 在 c 中拆分字符串

[英]Using strtok to split a string in c

在下面的代码中,我尝试拆分字符串以从字符串中获取由“,”分隔的名称。

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


int main(void)
{
    char *st = "Addison,Jayden,Sofia,Michael,Andrew,Lily,Benjamin";
    char *name[7];
    char *separate = ",";

    char *token = strtok(st, separate);
    int i = 0;
    while(token != NULL)
    {
        strcpy(name[i], token);
        token = strtok(NULL, ",");
        i++;
    }
    for (int j = 0; j < 7; j++)
    {
        printf("%s\n", name[j]);
    }
}

但是,当我尝试运行代码时遇到了分段错误。 我尝试调试它,似乎这行特定的代码是错误的来源:

char *token = strtok(st, separate);

谁能告诉我我做错了什么?

您声明了一个指向字符串文字的指针

char *st = "Addison,Jayden,Sofia,Michael,Andrew,Lily,Benjamin";

您不能更改字符串文字。 任何改变字符串文字的尝试都会导致未定义的行为。

来自 C 标准(6.4.5 字符串文字)

7 如果这些数组的元素具有适当的值,则未指定这些数组是否不同。 如果程序尝试修改这样的数组,则行为未定义

另一方面,标准 C 函数strtok更改传递给它的字符串。

来自 C 标准(7.23.5.8 strtok 函数)

4 strtok 函数然后从那里搜索包含在当前分隔符字符串中的字符。 如果没有找到这样的字符,则当前标记会延伸到 s1 指向的字符串的末尾,后续对标记的搜索将返回空指针。 如果找到这样的字符,它会被一个空字符覆盖,终止当前标记。 strtok 函数保存指向下一个字符的指针,下一次搜索标记将从该字符开始。

所以将声明替换为

char st[] = "Addison,Jayden,Sofia,Michael,Andrew,Lily,Benjamin";

您还声明了一个未初始化的指针数组。

char *name[7];

所以这个说法

strcpy(name[i], token);

还调用未定义的行为。

相反,你可以写

name[i] = token;

由于变量 i 包含 tfokens 的数量,因此通常这个循环

for (int j = 0; j < 7; j++)
{
    printf("%s\n", name[j]);
}

应该至少像(不使用幻数 7)那样重写

for (int j = 0; j < i; j++)
{
    puts( name[j] );
}

但是,当我尝试运行代码时遇到了分段错误

两个问题:

  • 试图更改不可编辑的字符串。
  • 尝试访问不属于进程的位置。

其中任何一个都可能导致崩溃。 (段错误)

内存分配问题
声明:

  char *name[7];

创建一个包含 7 个指针的数组。 它们中的每一个都需要分配内存才能以这种方式使用:

strcpy(name[i], token);

内存分配示例:

for(int i=0;i<7;i++)
{
    name[i] = malloc((maxNameLen+1)*sizeof(name[i]));
    if(!name[i]) 
    {
        //handle error
    }
}
//now each pointer has space for up to maxNameLen+1 characters

不可编辑的字符串

char *st = "Addison,Jayden,Sofia,Michael,Andrew,Lily,Benjamin";

要编辑的字符串不能采用这种形式(即字符串文字)。 它必须是可编辑的形式,以便strtok()更改它,就像解析时一样。 有许多可编辑的字符串形式,以下是两个示例:

//Create an editable form:
char st[] = {"Addison,Jayden,Sofia,Michael,Andrew,Lily,Benjamin"};

//Create an editable copy of original: (requires freeing when done using)
char *duplicate = strdup(st);
if(duplicate)
{
    //success duplicating, now parse duplicate.

这里还有另一个讨论解释了 C 中的可编辑/不可编辑字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM