首先,让我解释一些关于存储和字符串的内容。
有 3 种基本存储类型。自动、动态、静态。而静态的通常分为两种:只读和读写。动态和静态的很快就会对您有用。
自动变量是函数参数和局部变量。当您调用一个函数时,它们会被压入堆栈,而当函数返回时,它们会展开。
动态的一个是您在运行时分配给malloc 系列的那个。这就是我们创建动态数组的方式。完成free 后,您需要返回此源。如果不这样做,则称为内存泄漏,您可以使用工具valgrind 检查内存泄漏以及其他内存错误。它对于系统编程类非常有用。
而静态的是那些在程序的整个生命周期中都留在那里的。
如果您定义一个全局变量或static int i = 42,它将创建静态读写变量,以便您可以更改它。现在这是诀窍。
void foo() {
char *string1 = "hello, world" //static read-only
char string2[] = "hello, world" //automatic
}
因此,如果您尝试更改string1,您会遇到分段错误,但可以更改string2。我不知道为什么你没有通过decode_args("77900289008764") 得到分段错误,但我上了我的机器。 :D
现在是 C 字符串。它们以 null 结尾,这意味着每个字符串都有一个 (char) 0 字符结尾,表示它是字符串的结尾。 strtok 基本上用 NULL 字符替换模式,所以你有多个子字符串而不是一个。因此,从您的示例中,它将"77900289008764 NULL" 转换为"779 NULL 289 NULL 8764 NULL"
所以如果我是你,我会计算字符串中遇到的“00”并分配那么多字符指针。类似于:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char ** decode_args(char *arguments, char *delim) {
int num_substrings = 1; // Note that C don't initialize with 0 like java etc.
int len_delim = strlen(delim);
for (int i = 0;
arguments[i] != '\0' && arguments[i + 1] != '\0'; // Any of last 2 chars are terminator?
++i)
if (strncmp(arguments + i /* same as &arguments[i] */, delim, len_delim) == 0)
++num_substrings;
char **result = (char **) malloc(sizeof(char *) * (num_substrings + 1));
int i = 0;
char* token = strtok(arguments, delim);
while (token != NULL){
result[i] = token;
++i;
token = strtok(NULL, delim);
}
result[i] = NULL; //End of results. execv wants this as I remember
return result;
}
int main(int argc, char *argv[])
{
char str[] = "foo00bar00baz";
char **results = decode_args(str, "00");
for (int i = 0; results[i] != NULL; ++i) {
char *result = results[i];
puts(result);
}
free(results);
return 0;
}