C将Char * 2-D阵列展平为1-D

时间:2022-07-25 18:52:27

Say I have the following code:

说我有以下代码:

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

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

Now, how could I flatten this array into 1-D? Is it possible to do this such that new_1D_array[2] would still be 'cat', new_1D_array[400] would still be 'space', etc.?

现在,我怎么能把这个数组压平成1-D?有可能这样做,new_1D_array [2]仍然是'cat',new_1D_array [400]仍然是'空间',等等?

2 个解决方案

#1


You have a one-dimensional array of type pointer-to-char, with 1000 such elements. It's already 1D as far as arrays go, though it could be interpreted as a "jagged 2D array". If you want to convert this into one massive character array, you could do something like so, which requires calculating the size of the buffer you'll need to store it, and then flattening the array.

你有一个指向char类型的一维数组,有1000个这样的元素。就阵列而言,它已经是1D,尽管它可以被解释为“锯齿状的2D阵列”。如果你想将它转换成一个大型字符数组,你可以这样做,这需要计算你需要存储它的缓冲区的大小,然后展平数组。

Note that if you opt to use malloc instead of calloc, you'll have to manually set the last character to '\0' or 0 so that the final result is a NULL-delimited C-style string, and not just a character array, as the latter of the two won't work with C string operations, and the former will.

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

Code Listing


#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;
}

Sample Output


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

#2


The above answer beat me to the puch and looks great, but I'll finish my thoughts here.

上面的答案打败了我,看起来很棒,但我会在这里完成我的想法。

In this version every 11th byte of flatArray will contain the start of the strings from the original array, making it very easy to find the original strings from the ones before - i.e. string index 2 would start at 2*11 == index 22 and string 400 would start at 400 * 11 == index 4400. In this way, you would not need to iterate through the flat array counting terminators to find your old strings. The cost of this being that the flat array takes a bit more memory than the original.

在这个版本中,flatArray的每个第11个字节将包含原始数组中字符串的开头,这使得从之前的字符串中找到原始字符串非常容易 - 即字符串索引2将从2 * 11 ==索引22和字符串开始400将从400 * 11 ==索引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';
}

#1


You have a one-dimensional array of type pointer-to-char, with 1000 such elements. It's already 1D as far as arrays go, though it could be interpreted as a "jagged 2D array". If you want to convert this into one massive character array, you could do something like so, which requires calculating the size of the buffer you'll need to store it, and then flattening the array.

你有一个指向char类型的一维数组,有1000个这样的元素。就阵列而言,它已经是1D,尽管它可以被解释为“锯齿状的2D阵列”。如果你想将它转换成一个大型字符数组,你可以这样做,这需要计算你需要存储它的缓冲区的大小,然后展平数组。

Note that if you opt to use malloc instead of calloc, you'll have to manually set the last character to '\0' or 0 so that the final result is a NULL-delimited C-style string, and not just a character array, as the latter of the two won't work with C string operations, and the former will.

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

Code Listing


#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;
}

Sample Output


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

#2


The above answer beat me to the puch and looks great, but I'll finish my thoughts here.

上面的答案打败了我,看起来很棒,但我会在这里完成我的想法。

In this version every 11th byte of flatArray will contain the start of the strings from the original array, making it very easy to find the original strings from the ones before - i.e. string index 2 would start at 2*11 == index 22 and string 400 would start at 400 * 11 == index 4400. In this way, you would not need to iterate through the flat array counting terminators to find your old strings. The cost of this being that the flat array takes a bit more memory than the original.

在这个版本中,flatArray的每个第11个字节将包含原始数组中字符串的开头,这使得从之前的字符串中找到原始字符串非常容易 - 即字符串索引2将从2 * 11 ==索引22和字符串开始400将从400 * 11 ==索引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';
}