【问题标题】:How to create variable size array that contains strings?如何创建包含字符串的可变大小数组?
【发布时间】:2021-08-22 00:31:17
【问题描述】:

我在尝试创建包含字符串的可变大小数组时遇到问题。我试图创建一个多维数组,但这太难了。示例:

char *audio_types[8][40];           // 8 is number of string elements in the array by default; 40 is the maximum length of a string
audio_types = (char *) malloc(15);  // increasing number of strings in the array

free(audio_types);

此外,我试图创建可变大小的指针数组。示例:

char *audio_types[40];              // 40 is the maximum length of a string
*audio_types = (char *) malloc(8);  // setting number of strings to 8

free(audio_types);

问题是我不知道如何正确创建具有可变数量的字符串元素的数组。抱歉,我是 C 编程新手。简而言之,我的代码必须在一个数组中保存多个字符串元素。示例:

audio_types[0]  // some string...
audio_types[1]  // another string...
audio_types[2]  // more another sting... etc.

希望您能理解我要问的问题。感谢您的关注。

【问题讨论】:

  • char* audio_types[40]; 声明了一个“40 (char*) 的数组”。与 char[40]* audio_types 比较,它是“指向 (char[40]) 的指针”。通常,它会简单地写成char** audio_types,接受数组衰减为“指向字符指针的指针(即指向字符串的指针)”。
  • malloc(15); 分配 15 个字节。如果你想要 15 个指针 audio_types = malloc(15 * sizeof(char *)); 并且不要强制转换 malloc 的返回值:stackoverflow.com/questions/605845/…
  • 如果你分配一个固定大小的数组,你不能改变它。因此,请从一开始就使用 malloc,然后调用 realloc 来更改大小。
  • char *audio_types[8][40]; 是一个由 320 个字符指针组成的二维数组。您要写的是char *audio_types[8];,它是8 个字符指针。这里不需要 40,因为数组中的指针还没有指向任何地方 - 当你创建指针指向的字符串时使用 40。
  • *audio_types = (char *) malloc(8); 不起作用,因为*audio_types 是一个字符而不是指针,并且您将一个8 字节字符数组分配给单个字符。您的编译器可能会打印一条警告,表明您正在做一些非法的事情。你可能想要audio_types = malloc(8 * sizeof(char *));

标签: arrays c string variables multidimensional-array


【解决方案1】:

也许是这样的。添加新类型时,它将增加数组的大小。它还将跟踪您在数组中有多少种类型(如果您动态调整数组大小并且需要知道该数组中有多少元素,则需要它)。

#define AUDIO_TYPE_LENGTH 40

typedef char audio_type[AUDIO_TYPE_LENGTH];

typedef struct
{
    size_t size;
    audio_type audio_types[];
}audioTypes_t;

audioTypes_t *AddType(audioTypes_t *types, const char *type)
{
    size_t size = types ? types -> size : 0;

    types = realloc(types, sizeof(*types) + (size + 1) * sizeof(types -> audio_types[0]));

    if(types)
    {
        strncpy(types -> audio_types[size], type, sizeof(types -> audio_types[0] - 1));
        types -> audio_types[size][sizeof(types -> audio_types[0] - 1)] = 0; //making strncpy safe
        types -> size = size + 1;
    }
    return types;
}

【讨论】:

    【解决方案2】:

    您无法在 C 中更改数组的大小。每次您想要调整大小并将内容从旧数组传输到新数组时,都可以创建一个新数组。或者,您可以使用列表来存储您的字符串。

    【讨论】:

      【解决方案3】:

      当您在 C 中定义数组(char *audio_types[40]; 行)时,它会为数组中的 40 个字符指针创建一个连续的内存块。由于在定义数组时分配了内存,因此您不能使数组更长。为此,您需要一个 List 数据类型,或者当您想要添加一个新元素时创建一个新数组,该新元素是旧元素,新元素在末尾。

      【讨论】:

        【解决方案4】:

        char string[40] 是一个由 40 个字符组成的数组,最多可容纳 39 个字符(加上字符串终止符) - 最大大小无法更改,即使您存储包含 2 个字符的短字符串(加上字符串终止符)。

        char *string 是指向某些字符的指针 - 指针可以指向任何地方:单个字符或任何大小的字符数组。如果它指向一个字符数组(你可以使用 malloc() 来创建它,那么它可以被认为是一个“字符串”)

        char *array[8] 是一个由 8 个“字符串”组成的数组(实际上是 8 个指向字符的指针) 数组的大小无法更改,但指针可以指向任何地方:单个字符或任何大小的字符数组。如果指针指向一个字符数组(您可以使用 malloc() 生成,那么它们可以被认为是“字符串”)

        char array[8][40] 是一个 2D 数组,您可以将其视为 8 个“字符串”的数组 - 其中“字符串”定义为 40 个字符的数组,最多可容纳 39 个字符(加上字符串终止符)。您无法更改任一维度的大小。

        char **array 是一个指向char * 的指针——它可能只是一个“字符串”或一个“字符串”数组。大小不固定,可以动态创建。

        char *string1 = "asd"; 表示 string1 指向只读内存中的 4 个字符(“asd”加上字符串终止符)的数组 - 您无法更改字符串的内容,但您可以将 string1 指向任何您想要的位置。

        char string1[] = "asd"; 表示 string1 是一个由 4 个字符组成的数组,由编译器用 4 个字符(“asd”加上字符串终止符)填充 - 您可以更改数组的内容,但不能更改大小。

        所以如果你想要一个动态大小的字符串数组,你可以这样做:

        #include <stdio.h>  // printf
        #include <stdlib.h> // malloc, realloc, free
        #include <string.h> // strcpy, strdup
        
        int main()
        {
            // make an array of 8 string pointers
            int original_size = 8;
            char **array = malloc(original_size * sizeof(char *));
            
            // point each pointer to a string
            // you don't have to do this all at once if you don't want to
            for (int i=0; i<original_size; i++)
                array[i] = malloc(40 * sizeof(char)); // max of 39 plus the terminator
            
            // array[7] is already allocated so we can just use it as a string
            strcpy(array[7],"asd"); // the last string that we malloced
            
            // reallocate the array to be bigger
            int new_size = 15;
            array = realloc(array, new_size * sizeof(char *));
        
            // array[14] is a pointer that doesn't point anywhere
            // so we need to allocate space before filling it in
            array[14] = strdup("qwe"); // points 3 characters plus the string terminator
            
            printf("%s\n",array[7]);
            printf("%s\n",array[14]);
            
            // free the one we made with strdup
            free(array[14]);
            
            // free the 8 we malloced
            for (int i=0; i<original_size; i++)
                free(array[i]);
            
            // now free the array we malloced and then realloced
            free(array);
            
            return 0;
        }
        

        注意:该程序中没有错误检查,因为我不想掩盖基本想法 - 确保为您制作的任何程序添加错误检查

        试试https://onlinegdb.com/XQeyOGd0C

        【讨论】:

          猜你喜欢
          • 2016-12-08
          • 2019-06-12
          • 2016-01-17
          • 1970-01-01
          • 2019-06-28
          • 1970-01-01
          • 2013-04-09
          • 1970-01-01
          相关资源
          最近更新 更多