动态分配一个字符串数组
Dynamically allocate an array of strings
如何修复这段代码,使其打印数组中的单词?此外,这是为 n
个最大大小为 40 的单词动态分配内存的正确方法吗?
int main() {
int n;
char *arr;
int i;
printf("Give me a number:");
scanf("%d", &n);
arr = malloc(n * 40);
for (i = 0; i < n; i++)
{
printf("Give me a word: ");
scanf("%s", &arr[i]);
}
for (i = 0; i < n; i++)
{
printf("%s", arr[i]); //< --problem here
}
return 0;
}
这个:
for(i=0;i<n;i++){
printf("Give me a word: ");
scanf("%s",&arr[i]);
}
可能不是你想要的。
你可能想要这个:
for(i=0; i<n; i++){
printf("Give me a word: ");
scanf("%s", arr + i*40);
}
然后稍后:
for(i=0; i<n; i++){
printf("%s", arr + i*40);
}
请记住,C 中的字符串只是一个字符数组。
因此,在定义 char *arr
时,您正在创建一个 单个字符串 。如果您完成了 char **arr
,它将是一个 字符串数组 ,这就是您想要的。
但是,我发现allocating/freeing arrays of arrays of arrays on the heap 相当不方便,并且更喜欢'flattening' 将它们合并为一个数组。
这正是您对 arr = malloc(n*40)
所做的,但是后来当您将这个 字符 数组视为 字符串 数组时这样做了:
for(i=0; i<n; i++){
printf("Give me a word: ");
scanf("%s", &arr[i]);
}
请注意,这实际上是完全合法的(scanf
想要一个 char*
而你给了它一个),但这是一个逻辑错误,因为你给了它第 n
个character 当你想给它第 n
-th array.
哦,是的,别忘了稍后free(arr)
。
您的分配不是最好的,并且 printf
参数 arr[i]
需要一个 char*
但您传递给它一个 int
(一个 char
如果你喜欢)。
这是你应该如何做的,附有评论:
#include <stdio.h>
#include <stdlib.h> //for malloc
int main(){
int n;
int i;
printf("Give me a number:");
scanf("%d", &n);
//declare a variable of pointer to pointer to char
//allocate memory for the array of pointers to char,
//each one capable of pointing to a char array
char **arr = malloc(n * sizeof *arr);
if(arr == NULL){ //check for allocation errors
perror("malloc");
return EXIT_FAILURE;
}
//allocate memory for each individual char array
for(i = 0; i < n; i++){
arr[i] = malloc(40); //char size is always 1 byte
if(arr == NULL){ //check for allocation errors
perror("malloc");
return EXIT_FAILURE;
}
}
for (i = 0; i < n; i++){
printf("Give me a word: ");
//limit the size of read input to 39 charaters to avoid overflow,
//a nul character will be added by scanf
scanf("%39s", arr[i]);
}
for (i = 0; i < n; i++){
printf("%s\n", arr[i]);
}
for(int i = 0; i < n; i++){ //free the memory for each char array
free(arr[i]);
}
free(arr); //free array of pointers
return 0;
}
您也可以使用指向 40 个字符的数组的指针以更少的代码完成此操作,这将简化内存分配和释放:
带有注释的示例:
#include <stdio.h>
#include <stdlib.h> //for malloc
int main(){
int n;
int i;
printf("Give me a number:");
scanf("%d", &n);
//declare a pointer to array of chars and
//allocate memory for all the char arrays
char (*arr)[40] = malloc(n * sizeof *arr);
if(arr == NULL){ //check for allocation errors
perror("malloc");
return EXIT_FAILURE;
}
for (i = 0; i < n; i++){
printf("Give me a word: ");
scanf("%39s", arr[i]);
}
for (i = 0; i < n; i++){
printf("%s\n", arr[i]);
}
free(arr); //free allocated memory
return 0;
}
如何修复这段代码,使其打印数组中的单词?此外,这是为 n
个最大大小为 40 的单词动态分配内存的正确方法吗?
int main() {
int n;
char *arr;
int i;
printf("Give me a number:");
scanf("%d", &n);
arr = malloc(n * 40);
for (i = 0; i < n; i++)
{
printf("Give me a word: ");
scanf("%s", &arr[i]);
}
for (i = 0; i < n; i++)
{
printf("%s", arr[i]); //< --problem here
}
return 0;
}
这个:
for(i=0;i<n;i++){
printf("Give me a word: ");
scanf("%s",&arr[i]);
}
可能不是你想要的。
你可能想要这个:
for(i=0; i<n; i++){
printf("Give me a word: ");
scanf("%s", arr + i*40);
}
然后稍后:
for(i=0; i<n; i++){
printf("%s", arr + i*40);
}
请记住,C 中的字符串只是一个字符数组。
因此,在定义 char *arr
时,您正在创建一个 单个字符串 。如果您完成了 char **arr
,它将是一个 字符串数组 ,这就是您想要的。
但是,我发现allocating/freeing arrays of arrays of arrays on the heap 相当不方便,并且更喜欢'flattening' 将它们合并为一个数组。
这正是您对 arr = malloc(n*40)
所做的,但是后来当您将这个 字符 数组视为 字符串 数组时这样做了:
for(i=0; i<n; i++){
printf("Give me a word: ");
scanf("%s", &arr[i]);
}
请注意,这实际上是完全合法的(scanf
想要一个 char*
而你给了它一个),但这是一个逻辑错误,因为你给了它第 n
个character 当你想给它第 n
-th array.
哦,是的,别忘了稍后free(arr)
。
您的分配不是最好的,并且 printf
参数 arr[i]
需要一个 char*
但您传递给它一个 int
(一个 char
如果你喜欢)。
这是你应该如何做的,附有评论:
#include <stdio.h>
#include <stdlib.h> //for malloc
int main(){
int n;
int i;
printf("Give me a number:");
scanf("%d", &n);
//declare a variable of pointer to pointer to char
//allocate memory for the array of pointers to char,
//each one capable of pointing to a char array
char **arr = malloc(n * sizeof *arr);
if(arr == NULL){ //check for allocation errors
perror("malloc");
return EXIT_FAILURE;
}
//allocate memory for each individual char array
for(i = 0; i < n; i++){
arr[i] = malloc(40); //char size is always 1 byte
if(arr == NULL){ //check for allocation errors
perror("malloc");
return EXIT_FAILURE;
}
}
for (i = 0; i < n; i++){
printf("Give me a word: ");
//limit the size of read input to 39 charaters to avoid overflow,
//a nul character will be added by scanf
scanf("%39s", arr[i]);
}
for (i = 0; i < n; i++){
printf("%s\n", arr[i]);
}
for(int i = 0; i < n; i++){ //free the memory for each char array
free(arr[i]);
}
free(arr); //free array of pointers
return 0;
}
您也可以使用指向 40 个字符的数组的指针以更少的代码完成此操作,这将简化内存分配和释放:
带有注释的示例:
#include <stdio.h>
#include <stdlib.h> //for malloc
int main(){
int n;
int i;
printf("Give me a number:");
scanf("%d", &n);
//declare a pointer to array of chars and
//allocate memory for all the char arrays
char (*arr)[40] = malloc(n * sizeof *arr);
if(arr == NULL){ //check for allocation errors
perror("malloc");
return EXIT_FAILURE;
}
for (i = 0; i < n; i++){
printf("Give me a word: ");
scanf("%39s", arr[i]);
}
for (i = 0; i < n; i++){
printf("%s\n", arr[i]);
}
free(arr); //free allocated memory
return 0;
}