【问题标题】:How to fill an c array with unknown number of objects如何用未知数量的对象填充c数组
【发布时间】:2013-11-19 12:24:50
【问题描述】:

在填充过程完成之前,我需要用一些我不知道的对象填充一个 c 数组。

这是一个字符串数组。 另一个补充:我将一个字符串分成单词,所以我知道字符串的大小。云这有助于猜测正确的尺寸吗?

我需要一个可变数组之类的东西。

我怎样才能做到这一点?

【问题讨论】:

  • 使用 C++ 和 std::vector。
  • 我不能使用 C++ - C 是必需的!
  • @Claudio:请不要使用 C++ 标签,请不要使用 C++ 结构...
  • 你知道输入字符串的长度吗?
  • 不是确切的长度。但我想我可以用 sizeof 得到它

标签: c arrays


【解决方案1】:

更新
鉴于您正在对字符串进行分块(将其分成单词),您可以计算空格的数量,从而了解您需要多大的数组:

char givenString[] = "The quick brown fox jumps over the lazy dog";
int i;
for (i=0;givenString[i];givenString[i] == ' ' ? ++i : givenString++);
++i;// + 1 for the last word

现在i 将告诉您给定字符串中有多少个单词。然后你可以简单地做:

char **words = malloc(i*sizeof(char *));

然后开始您的业务。当然,您仍然必须分配每个字指针,并释放它。也许这是strtok 的一个不错的用例,顺便说一句:

//assuming i still holds the word-count
words[0] = strtok(givenString, " ");//
for (int j=1;j<i;++j)
{
    words[j] = strtok(NULL, " ");
}

不过,如果您要进行大量此类字符串拆分业务,您可能需要查看 strtok_r


您可以为此使用reallocrealloc 更改给定指针指向的内存块的大小。如果指针指向NULL,则realloc 的行为类似于malloc

char **ptr_array = NULL;
for (int i=1;i<argc;++i)
{
    ptr_array = realloc(ptr_array, i*sizeof(char *));
    ptr_array[i-1] = calloc(strlen(argv[i]) + 1, sizeof(char));
    strncpy(ptr_array[i-1], argv[i], strlen(argv[i]));
}

此代码会将所有参数复制到堆内存中,并为所需的内存一一分配内存。不要忘记free 电话,请注意!
这是一个完整的示例(包括free-calls)

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

int main()
{
    char **ptr_array = NULL;//pointer to pointers
    int i, argc = 5;//fake argc, argv
    char *argv[5] = {"me","foo","bar","zar", "car"};//dummy strings
    for (i=1;i<argc;++i)
    {
        ptr_array = realloc(ptr_array, i*sizeof(char *));//(re-)allocate mem
        ptr_array[i-1] = calloc(strlen(argv[i]) + 1, sizeof(char));//alloc str
        strncpy(ptr_array[i-1], argv[i], strlen(argv[i]));//copy
    }
    --argc;
    for(i=0;i<argc;++i)
    {
        printf("At index %d: %s\n", i, ptr_array[i]);//print
        free(ptr_array[i]);//free string mem
    }
    free(ptr_array);//free pointer block
    return 0;
}

我已经测试了这段代码,结果如你所料:

在索引 0:foo
在索引 1:bar
在索引 2:zar
在索引 3:汽车

【讨论】:

    【解决方案2】:

    您可以使用realloc 来声明您的数组并在需要时更改其大小。

    myStrArray = realloc(myStrArray, MaxArray * sizeof(char*));
    

    在大多数情况下,Realloc 将返回相同的内存块,直到它“满”,然后它将内存和内容移动到其他地方。

    请注意,这是一个指针数组,因此需要将字符串本身分配或分配给它。给第一个元素分配一个 100 字符的字符串,例如:

    myStrArray[0] = calloc(100, sizeof(char));
    

    始终使用free(realloc、calloc、malloc)释放分配的内存。

    【讨论】:

    • 这会导致每个元素都重新分配......不是吗?除了我猜在某些情况下尺寸可能太大
    • 仅在需要时 - 查看更新的答案。如果你想变得聪明,那么你可以将它分配为 1024 块或其他东西。
    • 另一个补充:我将一个字符串分成单词,所以我知道字符串的大小。云这有助于猜测正确的尺寸吗?
    • 当然!我不是 100% 确定你的意思(什么的大小?),但如果你知道你创建的字符串或数组的大小,然后分配那个数字。请记住,字符串需要一个额外的字符作为空终止符。
    • @AzzUrr1:由于您将字符串分成单词,我已经更新了我的答案,为您提供一种简单(如 2 行)的方法来确定您需要多少个指针分配,所以你不再需要realloc
    【解决方案3】:

    由于您先验知道数组的大小,因此您必须使用malloc() 为数组和其中包含的字符串动态分配内存。
    然后,您必须使用free() 在不再需要此内存时释放它。

    为了获得良好的局部性,您可能希望为数组中的字符串分配一块内存,考虑像 double-NUL terminated strings 这样的数据结构。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-31
      • 2013-01-17
      • 1970-01-01
      • 1970-01-01
      • 2013-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多