2010-02-06 7 views
1

J'ai des problèmes avec ce programme. L'idée est de lire des chaînes à partir d'un fichier texte et de les inclure dans un tableau dynamique 2D avec un nombre constant de colonnes et un nombre variable de lignes. Si le nombre initial de lignes n'est pas suffisant pour inclure toutes les chaînes, le bloc de mémoire du tableau doit être réaffecté. Le code compile bien mais l'exécution est impossible.Réallocation de tableau dynamique 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

Est-ce ce devoir? – batbrat

Répondre

0

fgets() retourne une valeur NULL lorsque la fin du fichier est atteinte ou il y a une erreur. Dans votre cas, lorsque vous archivez une boucle do-while, la condition feof(fp) n'est jamais atteinte lorsque vous quittez en vérifiant la valeur de retour de fgets().
Vous devriez faire comme ceci:


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

Spécification de la taille d'un argument de tableau n'a pas d'effet.

void func(char b[SIZE]); 

équivaut à

void func(char *b); 

Par conséquent, quand vous dites

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

Le sizeof évaluera à la taille d'un pointeur vers un char. Essayez d'utiliser

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

La même erreur se produit lorsque vous dites

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

que vous pourriez changer pour

*(p+n)=(char *)malloc(SIZE * sizeof(b)); 

Vous devez définir la taille de telle sorte que le tampon a l'espace pour toute la ligne, y compris le caractère de nouvelle ligne et aussi le \ 0. Sinon, strcpy ne fonctionnera pas correctement. Vous devriez utiliser strncopy de toute façon. Une fois que vous aurez effectué ces changements, fgets retournera 0 une fois la fin du fichier atteinte et votre programme signalera "Erreur lors de la redéfinition du fichier!". Vous devez modifier la terminaison de la boucle de lecture en conséquence.

En outre, vous n'utilisez pas réellement un tableau multidimensionnel. Vous utilisez un tableau de pointeurs vers des tableaux de caractères. En C, un tableau bidimensionnel serait alloué dans un bloc de mémoire contigu et accédé dans l'ordre des rangées. Ce serait OK dans votre cas, car toutes les lignes sont censées avoir la même longueur. Néanmoins, vous essayez de maintenir un tableau de pointeurs qui à son tour pointent vers les lignes. Cela fonctionne également mais n'est pas techniquement ce que nous appellerions un tableau multidimensionnel en C. Son appelé Iliffe vector ou simplement un tableau de tableaux . Dans l'ensemble, votre code est plutôt entrelacé et difficile à suivre. Vous devriez essayer de simplifier votre programme, ce qui facilitera grandement la recherche d'erreurs dans le futur.