【问题标题】:Dynamically adding elements to array C将元素动态添加到数组 C
【发布时间】:2020-02-26 16:46:04
【问题描述】:

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

这是我目前所拥有的:

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。我是初学者,所以我什至不知道“数组”是否是正确的词。应该构建什么数据类型,我该怎么做才能调用 execv 并使用当前打印在列表中的参数?

【问题讨论】:

  • 链接示例包含正确的参数类型:char * ls_args[],即您需要一个指向 char 的指针数组。您的主要挑战是在定义数组之前知道参数的数量。请注意strtok 会修改初始字符串。这可能会使首先确定参数的数量并稍后将它们复制到该数组中变得有点棘手。
  • 这能回答你的问题吗? Parse string into argv/argc
  • 嗯,好的,看起来你的分隔符应该是00。请注意,这不是strtok(..., "00"); 所做的; strtok() 仅支持单个字符分隔符(尽管是多个),所以这相当于 strtok(..., "0");。您可以使用strstr() 或类似名称。

标签: c arrays execv


【解决方案1】:

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

有 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;
}

【讨论】:

    【解决方案2】:

    试试这样的:

    #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 主要:

    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;
    }
    

    输出:

    【讨论】:

      猜你喜欢
      • 2016-02-09
      • 2014-06-19
      • 2013-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-19
      • 2015-11-21
      • 1970-01-01
      相关资源
      最近更新 更多