在C中动态初始化字符串数组
我知道我可以这样初始化一个字符串数组:
static const char *BIN_ELEMENTS[5] = { "0000\0", // 0 "0001\0", // 1 "0010\0", // 2 "0011\0", // 3 "0100\0", // 4 };
但我需要以动态的方式实现这一目标。 从文件中读取字符,并将它们插入到数组中。 然后将该数组复制到字符串数组中(如上所述)。
所以,假设我从文件中捕获了以下字符,并将它们插入到数组中,如下所示:
char number[5]; char *listOfNumbers[10]; number[0]='1'; number[1]='2'; number[2]='3'; number[3]='4'; number[4]='\0';
现在我想将整个数字内容复制到listOfNumers[0]
//中,这意味着我已将“1234”存储在listOfNumers的第0位。 留下9个位置来存储不同的数字。
所以我会做这样的事情:
listOfNumers[0] = number; //this actually seems to work.
但由于它是一个巨大的数字文件,我需要重用数组编号,以提取一个新的数字。 但是当我这样做时,之前存储在listOfNumers [0]中的内容会被覆盖,eventho我更新了新号码的新位置。 我该怎么处理?
这是我到目前为止:
char number[5]; // array for storing number int j=0; // counter int c; // used to read char from file. int k=0; // 2nd counter char*listOfNumbers[10]; // array with all the extracted numbers. FILE *infile; infile = fopen("prueba.txt", "r"); if (infile) { while ((c = getc(infile)) != EOF) { if(c != ' ' && c != '\n') number[k] = c; ++k; } // end inner if else { number[k] = '\0'; listOfNumbers[j] = number; printf("Element %d is: %s\n", j, listOfNumbers[j]); // prints correct value ++j; k=0; } // end else } // end while fclose(infile); } // end outer if printf("\nElement 0 is: %s\n", listOfNumbers[0]); // fails - incorrect value printf("Element 1 is: %s\n", listOfNumbers[1]); // fails - incorrect value printf("Element 2 is: %s\n", listOfNumbers[2]);
char * listOfNumbers [10]; 只保留10个指向char的内存。 并且listOfNumbers [j] = number仅存储数组编号的地址。 它不会复制数组编号的内容。 由于数字加法器永远不会改变,因此“列表”的10个元素中的每一个都指向相同的空间。
您需要为listOfNumber的每个元素使用malloc来保留空间。 你需要使用strcpy将数字的内容复制到当前的listOfNumber [k]。
listOfNumber[k] = malloc(strlen(number)+1); // reserve space of len strcpy(listOfNumbers[k],number) // copy string
不要忘记最后释放listOfNumbers的每个元素……还要注意你的文件可能包含超过10个字符串的事实……
你正在做的是你取一个5个char
的缓冲区,取其地址( number
衰减到listOfNumers[0] = number;
中的char*
)并将其存储在10个char*
的数组中。 当然,这不是你想要做的,因为最终结果是listOfNumbers
中的所有条目listOfNumbers
指向同一个缓冲区并且原始内存丢失。
您有两种方法可以解决此问题:
-
使用
strcpy()
作为H2CO3建议。 -
使用动态内存分配。 如果您正在使用glibc,
asprintf
和scanf
的分配扩展名是您的朋友(它是POSIX 2008)。
一般来说,我总是建议不要使用固定长度的缓冲区:我可以向你保证,当你施加的限制不再符合要求的时候会到来,然后你就可以进行扩展的错误搜寻方……以及那些分配function真的让生活变得更轻松。