带有字符串数组的 C 程序 malloc
C program malloc with array of strings
在程序开始时,我需要为未知数量且大小未知的字符串动态分配内存,以便稍后进行操作。要从我拥有的用户那里获取字符串数:
int main(int argc, char *argv[]){
int number = atoi(argv[1]);
到目前为止一切顺利。 "number" 现在持有用户在命令行上输入的用于执行代码的数字。现在到了我不太明白的部分。我现在需要动态存储字符串的长度以及字符串的内容。例如,我希望程序像这样运行:
Enter the length of string 1: 5
Please enter string 1: hello
Enter the length of string 2: ...
为此,我认识到我必须创建一个字符串数组。但是,我不太理解指针指针的概念,什么不是。我想要的也许是如何实现这一点的简化?
您从一开始就知道要存储 number
个字符串,因此您需要一个大小为 number
的数组来存储指向每个字符串的指针。
您可以使用 malloc
为 number
个字符指针动态分配足够的内存:
char** strings = malloc(number * sizeof(char*));
现在您可以循环 number
次并动态分配每个字符串:
for (int i = 0; i < number; i++) {
// Get length of string
printf("Enter the length of string %d: ", i);
int length = 0;
scanf("%d", &length);
// Clear stdin for next input
int c = getchar(); while (c != '\n' && c != EOF) c = getchar();
// Allocate "length" characters and read in string
printf("Please enter string %d: ", i);
strings[i] = malloc(length * sizeof(char));
fgets(strings[i], length, stdin);
}
既然你想同时保存长度和字符串,我建议你把它们放在一个结构中。喜欢
struct string
{
int length;
char* str;
};
现在您可以动态创建此结构的数组并为各个字符串动态分配内存。
类似于:
#include <stdio.h>
#include <stdlib.h>
struct string
{
int length;
char* str;
};
int main(void) {
int i;
char tmp[128];
int number = 3;
struct string* strings = malloc(number * sizeof *strings);
// read the input
for (i=0; i<number; ++i)
{
printf("length?\n");
if (fgets(tmp, sizeof tmp, stdin) == NULL)
{
printf("error 1");
exit(1);
}
int length;
if (sscanf(tmp, "%d", &length) != 1)
{
printf("error 2");
exit(1);
}
strings[i].length = length;
strings[i].str = calloc(length + 2, 1);
printf("string?\n");
if (fgets(strings[i].str, length + 2, stdin) == NULL)
{
printf("error 3");
exit(1);
}
if (strings[i].str[length] != '\n')
{
printf("error 4");
exit(1);
}
strings[i].str[length] = '[=11=]';
}
// print the strings
for (i=0; i<number; ++i)
{
printf("len=%d str=%s\n", strings[i].length, strings[i].str);
}
// Clean up, i.e. free the memory allocated
for (i=0; i<number; ++i)
{
free(strings[i].str);
}
free(strings);
return 0;
}
注意:您还应该检查所有 malloc
/calloc
是否成功,即不 return NULL。为了清楚起见,我跳过了那个。
在程序开始时,我需要为未知数量且大小未知的字符串动态分配内存,以便稍后进行操作。要从我拥有的用户那里获取字符串数:
int main(int argc, char *argv[]){
int number = atoi(argv[1]);
到目前为止一切顺利。 "number" 现在持有用户在命令行上输入的用于执行代码的数字。现在到了我不太明白的部分。我现在需要动态存储字符串的长度以及字符串的内容。例如,我希望程序像这样运行:
Enter the length of string 1: 5
Please enter string 1: hello
Enter the length of string 2: ...
为此,我认识到我必须创建一个字符串数组。但是,我不太理解指针指针的概念,什么不是。我想要的也许是如何实现这一点的简化?
您从一开始就知道要存储 number
个字符串,因此您需要一个大小为 number
的数组来存储指向每个字符串的指针。
您可以使用 malloc
为 number
个字符指针动态分配足够的内存:
char** strings = malloc(number * sizeof(char*));
现在您可以循环 number
次并动态分配每个字符串:
for (int i = 0; i < number; i++) {
// Get length of string
printf("Enter the length of string %d: ", i);
int length = 0;
scanf("%d", &length);
// Clear stdin for next input
int c = getchar(); while (c != '\n' && c != EOF) c = getchar();
// Allocate "length" characters and read in string
printf("Please enter string %d: ", i);
strings[i] = malloc(length * sizeof(char));
fgets(strings[i], length, stdin);
}
既然你想同时保存长度和字符串,我建议你把它们放在一个结构中。喜欢
struct string
{
int length;
char* str;
};
现在您可以动态创建此结构的数组并为各个字符串动态分配内存。
类似于:
#include <stdio.h>
#include <stdlib.h>
struct string
{
int length;
char* str;
};
int main(void) {
int i;
char tmp[128];
int number = 3;
struct string* strings = malloc(number * sizeof *strings);
// read the input
for (i=0; i<number; ++i)
{
printf("length?\n");
if (fgets(tmp, sizeof tmp, stdin) == NULL)
{
printf("error 1");
exit(1);
}
int length;
if (sscanf(tmp, "%d", &length) != 1)
{
printf("error 2");
exit(1);
}
strings[i].length = length;
strings[i].str = calloc(length + 2, 1);
printf("string?\n");
if (fgets(strings[i].str, length + 2, stdin) == NULL)
{
printf("error 3");
exit(1);
}
if (strings[i].str[length] != '\n')
{
printf("error 4");
exit(1);
}
strings[i].str[length] = '[=11=]';
}
// print the strings
for (i=0; i<number; ++i)
{
printf("len=%d str=%s\n", strings[i].length, strings[i].str);
}
// Clean up, i.e. free the memory allocated
for (i=0; i<number; ++i)
{
free(strings[i].str);
}
free(strings);
return 0;
}
注意:您还应该检查所有 malloc
/calloc
是否成功,即不 return NULL。为了清楚起见,我跳过了那个。