IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Manipulation des fichiers en C


précédentsommaire

IX. Solutions des exercices

IX-A. Enregistrement et chargement de données (VIII-A)

Écriture du tableau
Sélectionnez
#include <stdio.h>

int main()
{
    FILE * f = fopen("test.tab", "wb");
    if (f == NULL)
        perror("test.tab");
    else
    {
        int tab[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        fwrite(tab, sizeof(tab[0]), sizeof(tab) / sizeof(tab[0]), f);
        fclose(f);
        printf("Termine.\n");
    }

    return 0;
}
Chargement du tableau
Sélectionnez
#include <stdio.h>
#include <string.h>

int main()
{
    FILE * f = fopen("test.tab", "rb");
    if (f == NULL)
        perror("test.tab");
    else
    {
        int n, i, tab[10];
        n = fread(tab, sizeof(tab[0]), sizeof(tab) / sizeof(tab[0]), f);
        for(i = 0; i < n; i++)
            printf("%d\n", tab[i]);
        fclose(f);
    }

    return 0;
}

IX-B. Taille d'un fichier (VIII-B)

 
Sélectionnez
#include <stdio.h>
#include <string.h>

char * saisir_chaine(char * lpBuffer, int buf_size);
long filesize(FILE * f);

int main()
{
    char name[FILENAME_MAX];
    FILE * f;

    printf("Ce programme permet de determiner la taille d'un fichier.\n");
    printf("Entrez le nom du fichier : ");
    saisir_chaine(name, sizeof(name));

    f = fopen(name, "rb");
    if (f != NULL)
    {
        printf("La taille du fichier est : %ld bytes\n", filesize(f));
        fclose(f);
    }
    else
        perror(name);

    return 0;
}

char * saisir_chaine(char * lpBuffer, int buf_size)
{
    char * ret = fgets(lpBuffer, buf_size, stdin);

    if (ret != NULL)
    {
        char * p = strchr(lpBuffer, '\n');
        if (p != NULL)
            *p = '\0';
        else
        {
            int c;

            do
                c = getchar();
            while (c != EOF && c != '\n');
        }
    }

    return ret;
}

long filesize(FILE * f)
{
    long pos, size;

    pos = ftell(f); /* lire la position courante */
    fseek(f, 0, SEEK_END); /* aller a la fin du fichier */
    size = ftell(f); /* lire l'offset de la nouvelle position */
    fseek(f, pos, SEEK_SET); /* revenir a la position de depart */

    return size;
}

IX-C. Découpage et restitution d'un fichier (VIII-C)

Découpage
Sélectionnez
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define MAX_BUFSIZE 4096

char * saisir_chaine(char * lpBuffer, int buf_size);
long filesize(FILE * f);
void split_file(const char * szFile, FILE * f, size_t fsize, size_t bytes_max);

int main()
{
    FILE * f;
    char szFile[FILENAME_MAX - 3];

    printf("Entrez le nom du fichier a decouper : ");
    saisir_chaine(szFile, sizeof(szFile));
    f = fopen(szFile, "rb");

    if (f == NULL)
        perror(szFile);
    else
    {
        long fsize = filesize(f);
        
        if (fsize < 0)
            fprintf(stderr, "Une erreur s'est produite lors de la lecture de la taille du fichier.\n");
        else
        {
            double mbytes_max; /* taille maximale de chaque morceau en Mo */
    
            printf("Entrez la taille maximale autorisee pour chaque morceau (en Mo) : ");
            scanf("%lf", &mbytes_max);
    
            if (mbytes_max > 0)
            {
                size_t bytes_max; /* taille maximale de chaque morceau en o */
                long nb_morceaux;
    
                bytes_max = (size_t)ceil(mbytes_max * 1024 * 1024);
                nb_morceaux = fsize / bytes_max + (fsize % bytes_max != 0);
    
                if (nb_morceaux >= 100)
                    fprintf(stderr, "Cette valeur est trop petite par rapport au fichier.\n");
                else
                {
                    printf("Le fichier va etre decoupe en %ld morceaux.\n", nb_morceaux);
                    split_file(szFile, f, fsize, bytes_max);
                }
            }
        }

        fclose(f);
    }

    return 0;
}

char * saisir_chaine(char * lpBuffer, int buf_size)
{
    char * ret = fgets(lpBuffer, buf_size, stdin);

    if (ret != NULL)
    {
        char * p = strchr(lpBuffer, '\n');
        if (p != NULL)
            *p = '\0';
        else
        {
            int c;

            do
                c = getchar();
            while (c != EOF && c != '\n');
        }
    }

    return ret;
}

long filesize(FILE * f)
{
    long pos, size;

    pos = ftell(f);
    fseek(f, 0, SEEK_END);
    size = ftell(f);
    fseek(f, pos, SEEK_SET);

    return size;
}

void split_file(const char * szFile, FILE * f, size_t fsize, size_t bytes_max)
{
    size_t bufsize = bytes_max < MAX_BUFSIZE ? bytes_max : MAX_BUFSIZE;
    char * lpBuffer = malloc(bufsize);

    if (lpBuffer == NULL)
        fprintf(stderr, "Impossible d'allouer la memoire necessaire.\n");
    else
    {
        int i = 1, success = 1; /* i : numero de session */
        size_t total_to_write = fsize, total_written = 0;

        do
        {
            char out_name[FILENAME_MAX];
            FILE * f_out;

            sprintf(out_name, "%s.%02d", szFile, i);

            f_out = fopen(out_name, "wb");

            if (f_out == NULL)
            {
                perror(out_name);
                success = 0;
            }
            else
            {
                size_t session_max, session_to_write, session_written;

                session_max = total_to_write >= bytes_max ? bytes_max : total_to_write;
                session_to_write = session_max;
                session_written = 0;

                while (success && session_to_write > 0)
                {
                    size_t bytes_read, bytes_written;
                    double progression = (100.0 * session_written)/session_max;

                    printf("\rEcriture de %s : %.0f%% effectue", out_name, progression);
                    fflush(stdout);
                    bytes_read = fread(lpBuffer, 1, bufsize, f);

                    if (ferror(f))
                    {
                        putchar('\n');
                        perror(szFile);
                        success = 0;
                    }
                    else
                    {
                        bytes_written = fwrite(lpBuffer, 1, bytes_read, f_out);
                        session_written += bytes_written;
                        total_written += bytes_written;
                        session_to_write -= bytes_written;
                        total_to_write -= bytes_written;

                        if (ferror(f_out))
                        {
                            putchar('\n');
                            perror(out_name);
                            success = 0;
                        }
                    }
                }

                fclose(f_out);
                if (success)
                {
                    printf("\rEcriture de %s : succes.      \n", out_name);
                    i++;
                }
            }
        }
        while (success && total_written != fsize);

        free(lpBuffer);

        if (success)
            printf("Termine.\n");
    }
}
Restitution
Sélectionnez
#include <stdio.h>
#include <string.h>

#define BUF_SIZE 4096

char * saisir_chaine(char * lpBuffer, int buf_size);
long filesize(FILE * f);

char lpBuffer[BUF_SIZE];

int main()
{
    FILE * f;
    char szFile[FILENAME_MAX - 3];

    printf("Entrez le nom du fichier a reconstituer : ");
    saisir_chaine(szFile, sizeof(szFile));
    f = fopen(szFile, "wb");

    if (f == NULL)
        perror(szFile);
    {
        FILE * f_part;
        char part_name[FILENAME_MAX];
        int i = 1, success = 1;

        do
        {
            sprintf(part_name, "%s.%02d", szFile, i);

            f_part = fopen(part_name, "rb");

            if (f_part == NULL)
                perror(part_name);
            else
            {
                long partsize = filesize(f_part);
                
                if (partsize < 0)
                    printf("Une erreur s'est produite lors de la lecture de la taille du fichier.\n");
                else
                {
                    size_t bytes_read, session_bytes_written = 0;
    
                    do
                    {
                        double progression = (100.0 * session_bytes_written) / partsize;
                        
                        printf("\rCopie de %s : %.0f%% effectue", part_name, progression);
                        bytes_read = fread(lpBuffer, 1, BUF_SIZE, f_part);
                        if (ferror(f_part))
                        {
                            putchar('\n');
                            perror(part_name);
                            success = 0;
                        }
                        else
                        {
                            session_bytes_written += fwrite(lpBuffer, 1, bytes_read, f);
                            if (ferror(f))
                            {
                                putchar('\n');
                                perror(szFile);
                                success = 0;
                            }
                        }
                    }
                    while (success && bytes_read == BUF_SIZE);
    
                    fclose(f_part);
                    if (success)
                    {
                        printf("\rCopie de %s : succes.      \n", part_name);
                        i++;
                    }
                }
            }
        }
        while (lpBuffer != NULL && f_part != NULL);

        fclose(f);

        if (success)
            printf("Termine.\n");
    }

    return 0;
}

char * saisir_chaine(char * lpBuffer, int buf_size)
{
    char * ret = fgets(lpBuffer, buf_size, stdin);

    if (ret != NULL)
    {
        char * p = strchr(lpBuffer, '\n');
        if (p != NULL)
            *p = '\0';
        else
        {
            int c;

            do
                c = getchar();
            while (c != EOF && c != '\n');
        }
    }

    return ret;
}

long filesize(FILE * f)
{
    long pos, size;

    pos = ftell(f);
    fseek(f, 0, SEEK_END);
    size = ftell(f);
    fseek(f, pos, SEEK_SET);

    return size;
}

IX-D. Chiffrement et déchiffrement (VIII-D)

 
Sélectionnez
#include <stdio.h>
#include <string.h>

char * saisir_chaine(char * lpBuffer, int buf_size);
unsigned char f1(unsigned char c);
unsigned char f1_inv(unsigned char c);

int main()
{
    char choix[2];

    printf("Tapez 1 pour chiffrer et 2 pour dechiffrer ");
    saisir_chaine(choix, sizeof(choix));

    if (*choix != '1' && *choix != '2')
        fprintf(stderr, "Cette valeur est invalide.\n");
    else
    {
        char src[FILENAME_MAX];
        FILE * fsrc;

        printf("Entrez le nom du fichier a %s : ", *choix == '1' ? "chiffrer" : "dechiffrer");
        saisir_chaine(src, sizeof(src));

        fsrc = fopen(src, "rb");
        if (fsrc == NULL)
            perror(src);
        else
        {
            char dest[FILENAME_MAX];
            FILE * fdest;

            printf("Entrez le nom du fichier de destination : ");
            saisir_chaine(dest, sizeof(dest));

            if (strcmp(src, dest) == 0)
                printf("La source ne peut pas etre en meme temps la destination.\n");
            else
            {
                fdest = fopen(dest, "wb");
                if (fdest == NULL)
                    perror(dest);
                else
                {
                    /* Notre technique : chiffrement/dechiffrement octet par octet */

                    int c;
                    unsigned char (*f)(unsigned char) = *choix == '1' ? f1 : f1_inv;

                    printf("Traitement en cours ...");
                    fflush(stdout);

                    while ((c = getc(fsrc)) != EOF)
                        putc(f(c), fdest);

                    fclose(fdest);
                    printf("\nTermine.\n");
                }
            }

            fclose(fsrc);
        }
    }

    return 0;
}

char * saisir_chaine(char * lpBuffer, int buf_size)
{
    char * ret = fgets(lpBuffer, buf_size, stdin);

    if (ret != NULL)
    {
        char * p = strchr(lpBuffer, '\n');
        if (p != NULL)
            *p = '\0';
        else
        {
            int c;

            do
                c = getchar();
            while (c != EOF && c != '\n');
        }
    }

    return ret;
}

unsigned char f1(unsigned char c) /* Notre fonction de chiffrement */
{
    /* Principe : on fait decaler de maniere circulaire tous les bits de un pas vers la gauche */
    unsigned char msb = (c & 0x80) >> 7; /* Le bit le plus a gauche */
    c <<= 1;
    c |= msb;
    return c;
}

unsigned char f1_inv(unsigned char c) /* Notre fonction de dechiffrement */
{
    unsigned char lsb = c & 1; /* Le bit le plus a droite */
    c >>= 1;
    c |= (lsb << 7);
    return c;
}

X. Remerciements

Merci à ram-0000 pour sa relecture de cet article.


précédentsommaire

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2008 Melem. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.