我必须从stdin中读取一些字符(我不知道其中有多少字符,但不超过MAX),我想将它们存储在数组中。此代码段正确吗?
char *c1 = (char*) malloc(MAX * sizeof(char)); //may be too much
fgets(c, MAX, stdin);
int size = strlen(c1);
char *c2 = (char*) realloc(c1, size * sizeof(char));
free(c1);
或者,当您不知道要存储多少个元素时,有没有一种更优雅的方法来确定分配给数组的内存量?
在其中fgets()
,您可能c1
不是这样c
。
您可以这样做(如果您坚持使用realloc()):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 50
int main() {
char *c1 = malloc(MAX * sizeof(char));
if(!c1) {
printf("malloc() failed\n");
return -1;
}
fgets(c1, MAX, stdin);
int size = strlen(c1);
char* c2;
if(c1[size - 1] == '\n') {
c1[size - 1] = '\0';
c2 = realloc(c1, (size) * sizeof(char));
} else {
c2 = realloc(c1, (size + 1) * sizeof(char));
}
if(!c2) {
printf("realloc() failed\n");
return -1;
}
c1 = NULL;
printf("Input was: %s\n", c2);
free(c2);
return 0;
}
这里有一些评论:
您希望读取一个字符串,因此应使用char*
而不是int*
。
通常,您不希望fgets()
保留换行符,因此我使用c1[size - 1] = '\0';
,它将覆盖它。但是,如果用户输入了允许的最大字符,则将没有空间,因此我们检查换行符是否确实存储在缓冲区中。
在中realloc()
,您应该为字符串的大小PLUS NULL TERMINATOR分配空间。这就是现在的原因size+1
。但是,在我们覆盖换行符的情况下,则不需要这样做,因为我们已经将字符串的大小减小了一个,因此size
就足够了。
永远不要忘记取消分配您的内存。
但是,如果我是您,我会打印一条消息,警告用户输入MAX
字符并避免重新分配。
从流中读取字符,并将它们作为C字符串存储到str中,直到已读取(num-1)个字符或到达换行符或到达文件末尾为止,以先发生的为准。
因此,即使用户输入了更多内容,该程序也不会崩溃。
正如Paul正确评论的那样,使用第二个指针是一个非常好的主意,这样,如果realloc()
失败,我们将不会丢失数据。
另请注意,您不应释放c1
,因为此指针无效,应将其设置为NULL
。c1
可能会指向哪里c2
,因此,如果我们释放c1
,c2
则将指向垃圾。或者可能是整个内存块都转移到其他地方,因此c1
指向垃圾,我们正在尝试释放。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句