我正在编写一个简单的代码,该代码接受任何长度的用户的字符串,然后显示它。但是我的代码在接受字符串时无法正确执行,但未正确打印。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
main()
{
int i,len;
static int n=5;
char a[20];
char **s;
s=malloc(5*sizeof(char));
char *p;
for(i=0;i<n;i++)
{
scanf("%s",a);
if(*a=='1') /*to exit from loop*/
{
break;
}
len=strlen(a);
p=malloc((len+1)*sizeof(char));
strcpy(p,a);
s[i]=p;
if(i==n-1)
{
s=realloc(s,(5+i*5)*sizeof(char));
n=5+i;
}
}
for(i=0;i<n-1;i++)
{
printf("%s ",s[i]);
}
free(p);
p=NULL;
return 0;
}
有多个问题,但首先,最突出的是,
s=malloc(5*sizeof(char));
是错误的。s
是char **
类型,因此您需要在那里分配char *
的内存。换句话说,您希望s
指向char *
元素,因此,您需要相应地分配内存。
为了避免这些错误,切勿依靠硬编码数据类型,而是使用表单
s = malloc( 5 * sizeof *s); // same as s=malloc( 5 * sizeof (*s))
其中,大小OID基本上是根据变量的类型确定的。两个优点
- 您避免了上述错误。
- 代码变得更有弹性,您不需要更改
malloc()
语句,以防您选择更改数据类型
也就是说,scanf("%s",a);
也是潜在的危险,并且会导致预期输入的缓冲溢出。您应该始终使用最大场宽度限制输入扫描长度,例如
scanf("%19s",a); // a is array of dimension 20, one for terminating null
也就是说,对于逻辑的建议,当您不知道或不指定输入字符串的长度时,您不能将 string 类型用于 scan 输入。完成此操作的基本方法是
- 使用
malloc()
.
的分配函数,动态分配中等长度缓冲区 - 继续读取输入流,
fgetc()
或类似。 - 如果读取完成(例如,
EOF
的返回),您已经阅读了完整的输入。 - 如果分配的内存已经用完了,请重新分配原始缓冲区并继续步骤3。
,不要忘记 free()
内存。
否则,您可以使用fgets()
读取内存的块并继续进行真实性,如上所述。