动态添加元素到数组 C

Dynamically adding elements to array C

我正在尝试构建一个函数,该函数接受一串字符并提供由标记分隔的这些字符的列表。

这是我目前拥有的:

char * decode_args(char arguments[]){
  char* token = strtok(arguments, "00");
  while (token != NULL){
    printf("%s\n", token);
    token = strtok(NULL, "00");
  }
  return 0;
}

此函数打印我正在寻找的所需值。例如:

>decode_args("77900289008764")
779
289
8764

下一步是构建一个可以在 execv 命令中使用的数组。参数必须是一个数组。 An example here。我是初学者,所以我什至不知道 "array" 是否正确。应该构建什么数据类型,我该怎么做才能用当前正在列表中打印的参数调用 execv

尝试这样的事情:

#define MAX_ARGUMENTS 10

int decode_args(char arguments[], char ** pcListeArgs)
{
    int iNumElet = 0;
    char* token = strtok(arguments, "00");

    while ((token != NULL) && (iNumElet < MAX_ARGUMENTS -1)) 
    {
        size_t len = strlen(token);

        pcListeArgs [iNumElet] = (char*) calloc (len+1, sizeof (char));
        memset(pcListeArgs [iNumElet], 0, len+1); // reset content
        memcpy(pcListeArgs [iNumElet], token, len); // copy data

        token = strtok(NULL, "00");
        iNumElet++;
    }

    if ( iNumElet >= MAX_ARGUMENTS)
        return -1;

    return iNumElet;
}

和主要内容:

int main() {

    char *pListArgs[MAX_ARGUMENTS];

    char args[] = "77900289008764";

    int iNbArgs = decode_args (args, pListArgs);

    if ( iNbArgs > 0)
    {
        for ( int i=0; i<iNbArgs; i++)
            printf ("Argument number %d = %s\n", i, pListArgs[i]);

        for ( int i=0; i<iNbArgs; i++)
            free (pListArgs[i]);
    }

    return 0;
}

输出:

首先让我解释一些关于存储和字符串的内容。

有 3 种基本存储类型。自动、动态、静态。而静态的通常一分为二:只读和读写。动态和静态的很快就会对你有用。

自动变量是函数参数和局部变量。当你调用一个函数时,它们被压入堆栈,当函数 returns 时,它们被展开。

动态的是你在运行时用 malloc 系列分配的。这就是我们创建动态数组的方式。当您完成 free 后,您需要 return 这个来源。如果不这样做,则称为内存泄漏,除了其他内存错误外,您还可以使用工具 valgrind 检查内存泄漏。它对系统编程非常有用class。

而静态的是那些在程序的整个生命周期内都留在那里的。 如果您定义一个全局变量或 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] != '[=11=]' && arguments[i + 1] != '[=11=]'; // 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;
}