2010-02-06 5 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

ответ

0

fgets() возвращает NULL, если конец файла достигается или возникает ошибка. В вашем случае , поскольку вы проверяете цикл do-while, поэтому условие feof(fp) никогда не будет достигнуто, когда вы выходите при проверке возвращаемого значения fgets().
Вы должны сделать так:


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, как только будет достигнут конец файла, и ваша программа сообщит «Ошибка при записи файла!». Вы должны соответствующим образом изменить окончание цикла чтения.

Кроме того, вы фактически не используете многомерный массив. Вы используете массив указателей на массивы символов. В C 2-мерный массив будет выделен в непрерывном блоке памяти и доступен в строчном порядке. Это было бы нормально в вашем случае, потому что все строки должны иметь одинаковую длину. Тем не менее, вы пытаетесь сохранить массив указателей, которые, в свою очередь, указывают на строки. Это также работает, но технически то, что мы бы назвали многомерным массивом в C. Его называли Iliffe vector или просто массивом массивов.

В целом, ваш код довольно переплетается и трудно следовать. Вы должны попробовать и упростить свою программу, которая сделает поиск ошибок намного легче для вас в будущем.

Смежные вопросы