【问题标题】:C Flatten 2-D Array of Char* to 1-DC 将 Char* 的二维数组展平为一维
【发布时间】:2015-07-17 06:57:02
【问题描述】:

假设我有以下代码:

char* array[1000]; // An array containing 1000 char*

// So, array[2] could be 'cat', array[400] could be 'space', etc.

现在,我如何将这个数组展平为一维?是否可以这样做,使得 new_1D_array[2] 仍然是 'cat',new_1D_array[400] 仍然是 'space' 等等?

【问题讨论】:

  • 您需要知道数组第二维的大小,因为上面没有指定 - 除非它们包含 C 字符串,在这种情况下可以展平,但可能不保留根据需要对列表进行相同的索引。
  • 假设每个 char* 的长度最多为 10。这算作第二维吗?
  • “最多 10 个”表示它可能是一个锯齿状数组。您需要 100% 确定每个元素的大小,而不是最多将其视为真正的二维数组。如果长度为 8、6、7、9、5、10 等。展平变得很困难,除非你只是停在 C 字符串 NUL char 的末尾,如果没有遇到,则停在 10 (在这种情况下,你需要在新数组中以某种方式终止它。)
  • 嗯,没有。 char* array[1000] 已经是一维字符指针数组。
  • 那么,既然 char* array[1000] 已经是一维的,这是否意味着它使用单个连续的内存块?

标签: c arrays char flatten


【解决方案1】:

您有一个pointer-to-char 类型的一维数组,其中包含 1000 个这样的元素。就数组而言,它已经是一维的了,尽管它可以被解释为“锯齿状的二维数组”。如果你想把它转换成一个庞大的字符数组,你可以这样做,这需要计算你需要存储它的缓冲区的大小,然后将数组展平。

请注意,如果您选择使用 malloc 而不是 calloc,则必须手动将最后一个字符设置为 '\0'0,以便最终结果是 NULL 分隔的 C 样式字符串,而不仅仅是一个字符数组,因为两者中的后者不适用于 C 字符串操作,而前者可以。

代码清单


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

int main(void) {
        const char* array[] = { "one", "two", "three", "four" };
        size_t length = sizeof(array) / sizeof(char*);

        int i;
        int sum = 0;
        int count = 0;

        for (i=0; i<length; i++) {
                printf("Element #%d - %s\n", i, array[i]);
                sum += strlen(array[i]) + 1;
        }
        sum++;  // Make room for terminating null character

        char* buf;
        if ((buf = calloc(sum, sizeof(char))) != NULL) {
                for (i=0; i<length; i++) {
                        memcpy(buf+count, array[i], strlen(array[i]));
                        count += strlen(array[i]) + 1;
                        buf[count-1] = '#';
                }
                printf("Output Buffer: %s\n", buf);
                printf("Buffer size:%d - String Length:%d\n", sum, strlen(buf));
                free(buf);
                buf = NULL;
        }

        return 0;
}

样本输出


Element #0 - one
Element #1 - two
Element #2 - three
Element #3 - four
Output Buffer: one#two#three#four#
Buffer size:20 - String Length:19

【讨论】:

  • @casualresearcher 没问题。如果您需要帮助调整它,请随时发布 cmets。
【解决方案2】:

上面的答案让我大吃一惊,看起来很棒,但我会在这里完成我的想法。

在这个版本中,flatArray 的每 11 个字节都将包含原始数组中字符串的开头,这使得从之前的字符串中查找原始字符串变得非常容易 - 即字符串索引 2 将从 2*11 == index 22 和字符串 400 开始将从400 * 11 == index 4400 开始。这样,您无需遍历平面数组计数终止符来查找旧字符串。这样做的代价是平面数组比原始数组占用更多的内存。

char* array[1000];

// Malloc new buffer
char *flatArray = malloc(length * 1100);

for(i=0; i<1000; i++)
{  
    strncpy(&flatArray[i * 11], array[i], 10);
    flatArray[i * 11 + 10] = '\0';
}

【讨论】:

  • 大声笑 - 太慢了。 :)
  • 绝对是一个很好的例子。谢谢你发帖:)
猜你喜欢
  • 2015-07-21
  • 2011-02-03
  • 2011-07-26
  • 2014-09-10
  • 1970-01-01
  • 2018-02-03
  • 1970-01-01
  • 2021-11-23
  • 2019-11-27
相关资源
最近更新 更多