IX. Solutions des exercices▲
IX-A. Enregistrement et chargement de données (VIII-A)▲
Ecriture 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;
}
