2010-02-06 118 views
1

我有这个程序的问题。这个想法是从文本文件中读取字符串,并将它们包含在具有恒定列数和不同行数的2D动态数组中。如果初始行数不足以包含所有字符串,则必须重新分配数组的内存块。代码编译正常,但执行是不可能的。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)); 
} 
+1

这功课吗? – batbrat 2010-02-06 13:45:44

回答

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++; 
} 


2

指定数组参数的大小没有任何影响。

void func(char b[SIZE]); 

是相当于

void func(char *b); 

因此,当你说

case 1: *(p+n)=(char *)malloc(sizeof(b)); 

sizeof运算将计算为一个字符指针的大小。尝试使用

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文件!”。您应该相应地更改读取循环的终止。

此外,你实际上没有使用多维数组。您正在使用指向数组字符的指针数组。在C中,一个二维数组将被分配在一个连续的内存块中,并按行优先顺序访问。这在你的情况下是可以的,因为所有的行应该具有相同的长度。尽管如此,你正试图维护一个指向数组的指针数组。这也行得通,但在技术上我们不会称之为C中的多维数组。它被称为Iliffe vector或者仅仅是阵列阵列

总而言之,你的代码是相互交织在一起的,难以遵循。您应该尝试简化您的程序,以便将来为您找到更容易发现的错误。