如何在C语言中向动态数组中添加/删除字符串

5

我有一个已定义的数组示例:

char *arguments[] = {"test-1","test-2","test-3"};

我正在尝试添加通过命令行给出的参数输入。我尝试使用strcpy函数并通过数组元素传递,例如arguments[num+1] = argv[1],但仍然没有成功。

我知道这是一个非常简单的问题,但我不是一名有经验的程序员,而且我所有的经验都来自于更高级的编程语言(PHP、Perl)。

我在网上找到的最接近的工作示例是C program to insert an element in an arrayC program to delete an element from an array。但它们并不完全符合我的要求,并且它们正在处理我需要的字符而不是整数。

我的目标是找到一种方法,可以从动态数组中添加和删除字符串,该数组可以根据脚本的过程而增长和缩小。

感谢大家花时间和精力来帮助我。

下面是可工作代码示例:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

/* Set as minimum parameters 2 */
#define MIN_REQUIRED 2
#define MAX_CHARACTERS 46

/* Usage Instructions */
int help() {
  printf("Usage: test.c [-s <arg0>]\n");
  printf("\t-s: a string program name <arg0>\n");
  printf("\t-s: a string sample name <arg1>\n");
  return (1);
}

int main(int argc, char *argv[]) {

  if ( argc < MIN_REQUIRED ) {
    printf ("Please follow the instructions: not less than %i argument inputs\n",MIN_REQUIRED);
    return help();
  }
  else if ( argc > MIN_REQUIRED ) {
    printf ("Please follow the instructions: not more than %i argument inputs\n",MIN_REQUIRED);
    return help();
  }
  else {
    int size, realsize;
    char *input = NULL;

    char *arguments[] = {"test-1","test-2","test-3"};

    int num = sizeof(arguments) / sizeof(arguments[0]);

    printf("This is the number of elements before: %i\n",num);

    int i;
    for (i=0; i<num; i++) {
      printf("This is the arguments before: [%i]: %s\n",i,arguments[i]);
    }

    printf("This is the input argument: %s\n",argv[1]);
    printf("This is the array element: %i\n",num+1);

    input = (char *)malloc(MAX_CHARACTERS);
    if (input == NULL) {
      printf("malloc_in failled\n");
      exit(0);
    }

    memset ( input , '\0' , MAX_CHARACTERS);

    int length_before = strlen(input);
    printf("This is the length before: %i\n",length_before);
    strcpy(input , argv[1]);
    int length_after = strlen(input);
    printf("This is the length after: %i\n",length_after);

    //arguments[num+1] = input;

    strcpy(arguments[num+1],input);

    int num_2 = sizeof(arguments) / sizeof(arguments[0]);

    printf("This is the number of elements after: %i\n",num);

    for (i=0; i<num_2; i++) {
      printf("This is the arguments after [%i]: %s\n",i,arguments[i]);
    }

  } // End of else condition

  return 0;
} // Enf of int main ()

你不能这样使用数组。要么声明足够大的数组(例如,char *arguments [MAX_ARGUMENTS],其中常量是一个合理的数字),要么在知道有多少参数时动态分配它。 - keltar
2个回答

5
  1. "我的目标是找到一种方法来向动态数组中添加和删除字符串":

    char *arguments[] = {...} 是静态分配的,因此它不能作为"动态数组"。

  2. strcpy(arguments[num+1],input):

    当这个数组只有num个条目时,您无法访问arguments[num+1]


建议的解决方案-根据argc的值动态分配和初始化arguments

char* strings[] = {"test-1","test-2","test-3"};
int i, num = sizeof(strings) / sizeof(*strings);
char** arguments = malloc((num+argc-1)*sizeof(char*));
if (arguments == NULL)
    ; // Exit with a failure

for (i=0; i<num; i++)
{
    arguments[i] = malloc(strlen(strings[i])+1);
    if (arguments[i] == NULL)
        ; // Deallocate what's already been allocated, and exit with a failure
    strcpy(arguments[i],strings[i]);
}

for (i=0; i<argc-1; i++)
{
    arguments[num+i] = malloc(strlen(argv[i+1])+1);
    if (arguments[num+i] == NULL)
        ; // Deallocate what's already been allocated, and exit with a failure
    strcpy(arguments[num+i],argv[i+1]);
}

...

// Deallocate everything before ending the program

请注意,如果您在失败(或执行某些操作后)后要实际退出,则无需释放所有内容,因为退出会自动执行该操作。如果您尝试尽管出现错误仍要继续运行,则需要进行内存释放。 - Chris Dodd
@ChrisDodd:在我看来,这似乎取决于操作系统,而不是由标准定义的东西。 - barak manos
谢谢,我想我明白了如何解决这个小问题。我会试一下的。 - thanos

2

C语言中没有动态数组,arguments有一个静态大小,可以容纳3个元素。

strcpy(arguments[num+1],input);

这是一种未定义的行为,表达式arguments[num+1]访问了数组越界(在最后一个元素之后两个元素);没有任何神奇的重新分配或其他操作会发生。

通常情况下,您有三个选择:

  1. 您知道要存储多少项数据,并声明数组具有该大小。可以跟踪实际存储在其中的数字,或添加一些哨兵值(需要额外的空间!)来指示结束。
  2. 如果要存储的项目数量超过了上限,则中止程序(返回错误指示器,告诉用户输入数据太大等)。
  3. 查找mallocreallocfree

好的,我明白你的意思了。我以为我不需要指定数组的大小。我认为它可以根据它所包含的元素进行增加或减少。那么在高级编程语言中,数组是如何指定的呢?感谢您花费时间和精力来帮助我。 - thanos
不客气 :) 数组的大小是恒定的,没有重新调整大小的方法。高级语言并没有像C数组那样的东西。例如,Java数组更像是指向'malloc'(“new等价”的)内存的C指针(后者更灵活,例如,您可以在C中调整这种“Java数组”的大小)。例如,在Python或Haskell中的列表根本不是数组(在O(1)随机访问的意义上),它们是链表(您可以通过快速网络搜索找到C中的链表实现示例)。 - mafso
你可以自己编写数据结构,如果需要自动调整大小以获得类似于其他语言中列表的行为。许多容器格式已经在一些库中实现,例如Glib。在C项目开始时,通常会花费一些时间来规划使用哪些内存策略。这是你应该熟悉的事情。还与你的问题相关:http://stackoverflow.com/a/24894968/1741125 - mafso

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