C > tri par fusion des lignes d'un fichier et impress

Titretri par fusion des lignes d'un fichier et impress
Postée le20-03-2011
Affichée251
Mini-lien
Description

le nom de fichier est donné en argument (au main) les lignes sont enregistré par lire() dans tab[] puis trier par fusion. Erreur de segmentation avant le retour de inf().

EtatContient des erreurs. Contient des erreurs.
Code d'insertion
Options
Afficher les numéros de lignes  Mettre la source en plein ecran  Selectionner la source  Partager sur Facebook 
Téléchargement Telecharger en format txt  Telecharger en format pdf  Telecharger en format c
Plein ecran
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

enum {
  Ncar = 10 * 1024,
  IniNlig = 2,
};

char ** tab;
int ntab;   // nombre d'elements utilisables dans tab

int
inf(char *s1, char *s2){
  int a, b;
  if(*s1 >= '0' && *s1 <= '9'){
    if(*s2 >= '0' && *s2 <= '9'){
      sscanf(s1, "%d", &a);
      sscanf(s2, "%d", &b);
      if(a == b){
        while(*(s1++) != ' ');
        while(*(s2++) != ' ');
        s1++;
        s2++;
        return inf(s1, s2);
      }
      return (a < b);
    }
    return 1;
  }
  if(*s2 >= '0' && *s2 <= '9')
    return 0;
  return (strcmp(s1, s2) < 0);
}

int
min(int a, int b){
  if(a < b)
    return a;
  return b;
}

void
fusion(char *s1[], int n1,
       char *s2[], int n2,
       char *dest[]){
  int i1, i2;
  for(i1 = i2 = 0; i1 < n1 && i2 < n2;){
    printf("\n%d %d %d\n",i1,i2,i1+i2);
    if(inf(s1[i1], s2[i2])){
      printf("test22");
      strcpy(dest[i1 + i2], s1[i1++]);
    }else{
      printf("test33");
      strcpy(dest[i1 + i2], s2[i2++]);
    } printf("%s\n",dest[i1+i2]);
  }
  while(i1 < n1)
    strcpy(dest[i1 + i2], s1[i1++]);
  while(i2 < n2)
    strcpy(dest[i1 + i2], s2[i2++]);
}

void
trier(char *t[], int nel){
  char *tmp[nel];
  int i, ln;
  for(ln = 1; ln < nel; ln *= 2){
    for(i = 0; i + 2 * ln < nel; i += 2*ln){
      fusion(&t[i], ln,
             &t[i + ln], ln,
             &tmp[i]);
    }
    fusion(&t[i], min(ln, nel -i),
           &t[min(ln, nel - i)], nel - ln - i,
           &tmp[i]);
    memcpy(t, tmp, nel * sizeof t[0]);
  }
}

int
lire(FILE * fd){
  char line[Ncar];
  int i;
  for(i = 0; fgets(line, Ncar, fd) != NULL; i++){
    if (i == ntab){
      if (ntab == 0){ // premiere allocation
        ntab = IniNlig;
        tab = malloc(ntab * sizeof tab[0]);
      } else {        // faire grossir tab
        ntab *= 2;
        tab = realloc(tab, ntab * sizeof tab[0]);
      }
      assert(tab != 0);
    }
    tab[i] = strdup(line);
    assert(tab[i] != NULL);
  }
  return i;
}

int
main(int argc, char *argv[]) {
  FILE *fic;
  int nbl, i;
  // ouverture du fichier
  if(argc != 2){
    printf("Nom de fichier manquant");
    exit(1);
  }
  fic = fopen(argv[1], "r");
  if(fic == NULL){
    printf("Impossible d'ouvrir le fichier %s\n", argv[1]);
    exit(1);
  }
  nbl = lire(fic);
  trier(tab, nbl);
  for(i = 0; i < nbl; i++)
    printf("%s", tab[i]);

  // fermeture du fichier
  if(fclose(fic) == EOF) {
    printf("Probleme de fermeture du fichier %s", argv[1]);
    exit(1);
  }
  free(tab);
  return 0;
}