我有这个程序的问题。我们的想法是从文本文件中读取字符串,并将它们包含在具有恒定列数和不同行数的2D动态数组中。如果初始行数不足以包含所有字符串,则必须重新分配阵列的内存块。代码正在编译好,但执行是不可能的。
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define SIZE 80
#define DELTA 5
char** include(char b[SIZE],char** p,int n,int k,int flag);
void output(char **p,int k);
int main(void)
{
char **ptr;
FILE *fp;
int i=0,koef=1;
char buffer[SIZE];
if((ptr=(char **)malloc(DELTA*sizeof(char *)))==NULL){
printf("Error!Memory not allocated!\n");
exit(1);
}
if((fp=fopen("test.txt", "r")) == NULL) {
printf("Cannot open file.\n");
exit(1);
}
do{
if(fgets(buffer,sizeof(buffer),fp)==NULL){
printf("Error while reding file!\n");
exit(1);
}
if(i<(DELTA*koef))
ptr=include(buffer,ptr,i,koef,1);
else {
koef++;
ptr=include(buffer,ptr,i,koef,2);
}
i++;
}while(!feof(fp));
free(ptr);
return 0;
}
char** include(char b[SIZE],char** p,int n,int k,int flag)
{
switch(flag){
case 1: *(p+n)=(char *)malloc(sizeof(b));
strcpy( *(p+n),b);
break;
case 2: if((p=(char **)realloc(p,k*DELTA*sizeof(char *)))==NULL){
printf("Error!Memory not allocated!\n");
exit(1);
}
*(p+n)=(char *)malloc(sizeof(b));
strcpy(*(p+n),b);
break;
}
return p;
}
void output(char **p,int k)
{
int j;
for(j=0;j<k;j++)
printf("%s\n",*(p+j));
}
答案 0 :(得分:2)
指定数组参数的大小无效。
void func(char b[SIZE]);
相当于
void func(char *b);
因此,当你说
时case 1: *(p+n)=(char *)malloc(sizeof(b));
sizeof将计算为指向char的指针的大小。尝试使用
case 1: *(p+n)=(char *)malloc(SIZE * sizeof(b));
如果您说
,则会发生同样的错误*(p+n)=(char *)malloc(sizeof(b));
您可以将其更改为
*(p+n)=(char *)malloc(SIZE * sizeof(b));
您应该设置大小,以便缓冲区有整个行的空间,包括换行符和终止\ 0。否则,strcpy将无法正常工作。无论如何你应该使用strncopy。完成这些更改后,一旦达到文件末尾,fgets将返回0,并且程序将报告“reding file!”时出错。您应该相应地更改读取循环的终止。
此外,您实际上并未使用多维数组。您正在使用指向字符数组的指针数组。在C中,二维数组将被分配在连续的存储器块中并以行主要顺序访问。这样就可以了,因为所有行都应该具有相同的长度。然而,您正在尝试维护一个指针数组,这些指针又指向行。这也有效,但在技术上我们称之为C中的多维数组。它称为Iliffe vector或简称数组。
总而言之,您的代码相互交织,难以理解。您应该尝试简化您的程序,这将使您在将来更容易发现错误。
答案 1 :(得分:0)
fgets()在到达文件末尾或出现错误时返回NULL。在你的情况下,
因为您正在检查do-while
循环,所以当您在检查fgets()的返回值时退出时,永远不会达到条件feof(fp)
。
你应该这样做:
while(fgets(buffer,sizeof(buffer),fp)!=NULL)
{
if(ferror(fp))
{
printf("Error Reading file\n");
exit(1);
}
if(i <(DELTA*koef))
ptr=include(buffer,ptr,i,koef,1);
else {
koef++;
ptr=include(buffer,ptr,i,koef,2);
}
i++;
}