#include #include #include #include #include #include "vector.h" /** Renvoie un pointeur vers un nouveau vecteur vide ou bien NULL s'il y a eu un probleme. */ struct vector_t *newVec() { struct vector_t *pv = calloc(sizeof(struct vector_t), 1); return pv; } /** Libere toutes les structures de donnees accessible a partir de pv. Libere egalement la zone pointee par pv */ void deleteVec(struct vector_t *pv) { // Inutile pour l'exercice 3 } /** Ajoute une copie de la string s a la fin du vecteur pv. Renvoie le rang dans le vecteur de la chaine ajoutee ou bien -1 s'il y a eu un problème. */ int pushBack(struct vector_t *pv, char *s) { pv->elem = realloc(pv->elem, (pv->nbElem+1)*sizeof(char*)); if (pv->elem == NULL) { return -1; } pv->elem[pv->nbElem] = malloc(strlen(s)+1); if (pv->elem[pv->nbElem] == NULL) { return -1; } strcpy(pv->elem[pv->nbElem], s); pv->nbElem++; return pv->nbElem - 1; } /** Renvoie l'element place a la case rank dans pv ou NULL si rank est en dehors des bornes de pv. */ char *getElem(const struct vector_t *pv, int rank) { if ((rank < 0) || (rank >= pv->nbElem)) { return NULL; } return pv->elem[rank]; } /** Cree un nouveau vecteur en initialisant son contenu avec les informations trouvees dans le fichier de nom filename. S'il y a un souci dans l'acces au fichier filename, affiche un message d'erreur et renvoie NULL. NB : le fichier est structure de la maniere suivante - Les 4 premiers octets contiennent le nombre, ecrit en binaire, d'elements du vecteur - Ensuite, pour chaque element du vecteur, il y a 4 octets contenant la longueur, ecrite en binaire, que doit avoir la zone memoire pour stocker la chaine de caracteres qui va etre lue ensuite (NB : cette longueur prend en compte le '\0' final), puis les octets de la chaine de caracteres (y compris le '\0' final). */ struct vector_t *loadVec(char *filename) { struct vector_t *pv; // TODO A completer // Corrige pv = newVec(); if (pv == NULL) { return NULL; } FILE *f = fopen(filename, "r"); if (f == NULL) { error_at_line(0, errno, __FILE__, __LINE__, "Soucis lors de l'ouverture du fichier \"%s\"", filename); return NULL; } int nb; if (fread(&nb, sizeof(nb), 1, f) != 1) { error_at_line(0, errno, __FILE__, __LINE__, "Soucis lors de la lecture du fichier \"%s\"", filename); fclose(f); return NULL; } int i; int tailleBuffer = 2048;//Nous prenons une taille initiale qui devrait etre assez grande pour contenir toutes les strings que la fonction va lire dans la suite. char *pBuffer = malloc(tailleBuffer); if (pBuffer == NULL) { error_at_line(0, errno, __FILE__, __LINE__, "Souci avec malloc lors de la lecture du fichier \"%s\"", filename); deleteVec(pv); fclose(f); return NULL; } for (i = 0 ; i < nb ; i++) { int taille; if (fread(&taille, sizeof(taille), 1, f) != 1) { error_at_line(0, errno, __FILE__, __LINE__, "Soucis lors de la lecture du fichier \"%s\"", filename); free(pBuffer); deleteVec(pv); fclose(f); return NULL; } if (taille > tailleBuffer) { tailleBuffer = taille; pBuffer = realloc(pBuffer, tailleBuffer); } if (fread(pBuffer, 1, taille, f) != taille) { error_at_line(0, errno, __FILE__, __LINE__, "Soucis lors de la lecture du fichier \"%s\"", filename); free(pBuffer); deleteVec(pv); fclose(f); return NULL; } pushBack(pv, pBuffer); } free(pBuffer); if (fclose(f) < 0) { error_at_line(0, errno, __FILE__, __LINE__, "Soucis lors de la fermeture du fichier \"%s\"", filename); } return pv; } /** Sauvegarde le vecteur pv dans le fichier binaire de nom filename (format du fichier explique dans loadVec). Renvoie 0 si tout s'est bien passe et -1 sinon (apres avoir affiche un message d'erreur explicatif) */ int saveVec(struct vector_t *pv, char *filename) { // TODO A completer // Corrige FILE *f = fopen(filename, "w"); if (f == NULL) { error_at_line(0, errno, __FILE__, __LINE__, "Soucis lors de l'ouverture du fichier \"%s\"", filename); return -1; } if (fwrite(&(pv->nbElem), sizeof(pv->nbElem), 1, f) != 1) { error_at_line(0, errno, __FILE__, __LINE__, "Soucis lors de l'ecriture du fichier \"%s\"", filename); fclose(f); return -1; } int i; for (i = 0 ; i < pv->nbElem ; i++) { int taille = strlen(pv->elem[i]) + 1; if (fwrite(&taille, sizeof(taille), 1, f) != 1) { error_at_line(0, errno, __FILE__, __LINE__, "Soucis lors de l'ecriture du fichier \"%s\"", filename); fclose(f); return -1; } if (fwrite(pv->elem[i], 1, taille, f) != taille) { error_at_line(0, errno, __FILE__, __LINE__, "Soucis lors de l'ecriture du fichier \"%s\"", filename); fclose(f); return -1; } } if (fclose(f) < 0) { error_at_line(0, errno, __FILE__, __LINE__, "Soucis lors de la fermeture du fichier \"%s\"", filename); } return 0; }