把字符串分割成字符串数组(C语言)

39

我不是完全确定如何在C中实现这个:

char* curToken = strtok(string, ";");
//curToken = "ls -l" we will say
//I need a array of strings containing "ls", "-l", and NULL for execvp()

我该如何做到这一点?


4
如果你希望以空格为分隔符进行拆分,为什么会指定“;”作为分隔符? - Oliver Charlesworth
2
例如:string =“ls -l; date; set +v” - Jordan
2个回答

67

既然您已经了解了 strtok,那么可以继续使用相同的方法,使用空格 (' ') 作为分隔符拆分字符串,然后使用 realloc 等函数增加包含要传递给 execvp 的元素的数组的大小。

请参考以下示例,但请注意 strtok 将修改传递给它的字符串。 如果不希望发生这种情况,则需要复制原始字符串,使用 strcpy 或类似的函数进行复制。

char    str[]= "ls -l";
char ** res  = NULL;
char *  p    = strtok (str, " ");
int n_spaces = 0, i;


/* split string and append tokens to 'res' */

while (p) {
  res = realloc (res, sizeof (char*) * ++n_spaces);

  if (res == NULL)
    exit (-1); /* memory allocation failed */

  res[n_spaces-1] = p;

  p = strtok (NULL, " ");
}

/* realloc one extra element for the last NULL */

res = realloc (res, sizeof (char*) * (n_spaces+1));
res[n_spaces] = 0;

/* print the result */

for (i = 0; i < (n_spaces+1); ++i)
  printf ("res[%d] = %s\n", i, res[i]);

/* free the memory allocated */

free (res);

res[0] = ls
res[1] = -l
res[2] = (null)

1
@JordanCarney 很高兴为您服务。 - Filip Roséen - refp
@FilipRoséen-refp,您能解释一下在打印和释放内存之前的最后一个代码块吗?即:/* 重新分配一个额外的元素用于最后一个NULL */?我很难理解它。 - Honinbo Shusaku
@Abdul,我认为通常每个数组末尾都有一个空字符,这样计算机才能区分两个不同的数组。 - Charles
如果我将这个代码块封装成一个函数并返回res指针,那么在释放我分配给res的指针后,会出现警告:warning: attempt to free a non-heap object [-Wfree-nonheap-object]。你有什么想法是什么原因导致了这个问题吗? - MattSom

6

这里是一个从MSDN上借用的如何使用strtok的示例

需要调用它多次才能得到相关部分。 token char* 是您需要将其放入数组中的部分(您可以弄清楚该部分)。

char string[] = "A string\tof ,,tokens\nand some  more tokens";
char seps[]   = " ,\t\n";
char *token;

int main( void )
{
    printf( "Tokens:\n" );
    /* Establish string and get the first token: */
    token = strtok( string, seps );
    while( token != NULL )
    {
        /* While there are tokens in "string" */
        printf( " %s\n", token );
        /* Get next token: */
        token = strtok( NULL, seps );
    }
}

我理解到这个程度,但这并没有给我从令牌中得到字符串数组的方法。我猜我不理解其中的具体部分。 - Jordan
为什么要使用 token = strtok(NULL, seps);?为什么要使用 NULL - Charles
@c650请查看MSDN链接页面,后续调用需要使用'NULL'。 - Chris O
1
啊,是的。我经过了很多 Google 搜索,发现 strtok() 函数使用一个静态变量来保存其位置。 - Charles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接