【问题标题】:How to create jagged array of array of strings如何创建字符串数组的锯齿状数组
【发布时间】:2019-08-19 05:54:15
【问题描述】:

我正在编写一个接受命令行参数的程序,我想使用字符串“PIPE”分隔所有参数,例如我可以编写 ls -la PIPE wc。 我的代码

char **args = argv;
int pipes=0;
while(*args)
{
    if(strcmp("PIPE",*args) == 0)
    {
        pipes++;
    }
    args++;
}
int *pipeIndexes = NULL;
if(pipes > 0)
{
    pipeIndexes=(int *)malloc(pipes*sizeof(int));
    args = argv;
    pipeIndexes[pipes];
    int counter=0,i=0;
    while(*args)
    {
        if(strcmp("PIPE",*args) == 0)
        {
            pipeIndexes = (int *)realloc(pipeIndexes,sizeof(int)*(counter+1));
            pipeIndexes[counter] = i;
            counter++;
        }
        i++;
        args++;
    }
}

现在我想做的是创建另一个数组来存储每个程序的参数?例如。

programs = { {"ls","-la"},{"wc"}}

【问题讨论】:

  • 我给出了一个建议和执行示例的答案,我在每个构建(子)数组的末尾添加了 NULL 来标记它们的末尾,就像 argv 末尾有一个 NULL 一样跨度>
  • @bruno 谢谢我想我忘了标记是一个解决方案。我有一个问题,为什么要为 n+2 分配内存?我知道 +1 最后是 NULL 但为什么 + 2?
  • 是 n+2,因为 +1 表示新元素,+1 表示最后添加的 NULL(n 在 malloc 之后 递增)

标签: c malloc realloc jagged-arrays


【解决方案1】:

恭喜,您发现了char *** 的用例。 C 中的交错数组最好实现为指针数组,因此您需要一个(动态分配的)指针数组。

在下面的 sn-p(未经测试)中,将根据需要调用 realloc 以增加数组作为练习。

  char ***programs = malloc(10 * sizeof(char **)); /* arbitrary small size */
  int prog = 0, arg = 0;
  for (int i = 1; i < argc; i++) {
    if (strcmp(argv[i], "PIPE") == 0) {
      programs[prog][arg] = NULL;
      arg = 0;
      prog++;
      /* realloc programs if needed */
      programs[prog] = malloc(20 * sizeof(char *));
    } else {
      programs[prog][arg++] = argv[i];
      /* realloc programs[prog] if needed */
    }
  }
  programs[prog][arg] = NULL;
  /* realloc programs if needed */
  programs[++prog] = NULL;

【讨论】:

    【解决方案2】:

    每个(子)数组都以 NULL 结束以标记其结束的提议,例如 ls -la PIPE wc 产生 { {"ls","-la",NULL},{"wc",NULL},NULL}

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char ** argv)
    {
      if (argc == 1) {
        puts("at least an argument must be given");
        return -1;
      }
    
      char *** commands = NULL;
      size_t nCommands = 0;
    
      do {
        commands = realloc(commands, (nCommands + 2)*sizeof(char **));
    
        char ** command = NULL;
        size_t n = 0;
    
        while ((*++argv != NULL) && strcmp(*argv, "PIPE")) {
          command = realloc(command, (n + 2)*sizeof(char *));
          command[n++] = *argv; /* may be strdup(*argv) */
        }
        if (n == 0)
          puts("invalid PIPE");
        else {
          command[n] = NULL; /* marks the end */
          commands[nCommands++] = command;
        }
      } while (*argv);
    
      if (nCommands == 0)
        puts("no command");
      else {
        commands[nCommands] = NULL; /* marks the end */
    
        /* debug, print result, free ressources */
        char *** pcommands = commands;
    
        while (*pcommands) {
          char ** pcommand = *pcommands;
    
          while (*pcommand)
            printf("%s ", *pcommand++);
          putchar('\n');
          free(*pcommands++);
        }
        free(commands);
      }   
    }
    

    编译和执行:

    /tmp % gcc -g -pedantic -Wall -Wextra aa.c
    /tmp % ./a.out ls -la PIPE wc
    ls -la 
    wc 
    /tmp % ./a.out ls
    ls 
    /tmp % ./a.out 
    at least an argument must be given
    /tmp % ./a.out ls PIPE PIPE wc
    invalid PIPE
    ls 
    wc 
    vxl15036 /tmp % ./a.out ls PIPE 
    invalid PIPE
    ls 
    

    valgrind下执行

    /tmp % valgrind ./a.out ls -la PIPE wc
    ==9808== Memcheck, a memory error detector
    ==9808== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
    ==9808== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
    ==9808== Command: ./a.out ls -la PIPE wc
    ==9808== 
    ls -la 
    wc 
    ==9808== 
    ==9808== HEAP SUMMARY:
    ==9808==     in use at exit: 0 bytes in 0 blocks
    ==9808==   total heap usage: 5 allocs, 5 frees, 96 bytes allocated
    ==9808== 
    ==9808== All heap blocks were freed -- no leaks are possible
    ==9808== 
    ==9808== For counts of detected and suppressed errors, rerun with: -v
    ==9808== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-14
      • 2011-02-04
      • 2013-05-28
      • 1970-01-01
      • 1970-01-01
      • 2019-07-15
      • 2015-09-23
      • 1970-01-01
      相关资源
      最近更新 更多