Semaine 6
Projet, images,
lire et écrire des fichiers
lire et écrire des fichiers
SSIE Programmation en C, Thomas Lochmatter, 2019
1
Pour commencer le projet
projet-linux.zip
projet.c
image.c
image.h
Makefile
Les bibliothèques libpng et libjpeg sont déjà installées.
projet-windows.zip
projet.c
image.c
image.h
Makefile
libpng
libjpeg
Compilées pour MinGW sous Windows.
projet-mac.zip
projet.c
image.c
image.h
Makefile
libpng
libjpeg
Compilées pour Mac OS.
3
4
5
Image
struct Image { int width; int height; struct Pixel * pixels; };
// Fonctions struct Image image; image_create(&image, 1000, 600); image_read(&image, "image.jpg"); image_write_to_png(&image, "modifie.png"); image_write_to_jpeg(&image, "modifie.jpeg", 95); image_free(&image);
Pixel
struct Pixel { unsigned char r; unsigned char g; unsigned char b; unsigned char a; };
// Modifier un pixel image.pixels[i].r = 68; image.pixels[i].g = 153; image.pixels[i].b = 238;
6
SVG |
image vectorielle fichier texte avec des polygones |
||
PNG |
image matricielle compression sans pertes (lossless) |
![]() |
60x17 pixels |
JPEG |
image matricielle compression avec pertes (lossy) |
![]() |
60x17 pixels qualité 80 |
7
JPEG
8
9
Ouvrir et fermer des fichiers
// HIDE #include <stdio.h> #include <stdlib.h> // SHOW // Ouvrir un fichier pour le lire ("r"), // pour l'écrire ("w"), ou pour ajouter ("a") FILE * fichier = fopen("earthquake1", "r"); // Vérification if (fichier == NULL) { printf("Impossible d'ouvrir 'earthquake1'.\n"); return 1; } // Lire ou écrire ... // Fermer le fichier fclose(fichier);
Le mode
"w"
détruit le fichier s'il existe. Le mode "a"
garde le, et ajoute à la fin.10
Lire et écrire des fichiers texte: fgets, fprintf
// HIDE #include <stdio.h> #include <stdlib.h> FILE * fichier = ...; // SHOW char ligne[100]; while (fgets(ligne, 100, fichier) != NULL) { // Traiter la ligne double valeur = atof(ligne); ... }
// HIDE #include <stdio.h> #include <stdlib.h> FILE * fichier = ...; // SHOW double valeur = 0.661; fprintf(fichier, "Valeur: %0.3f\n", valeur);
A chaque appel,
fgets
lit la prochaine ligne du fichier.11
Lire et écrire des tableaux: fread, fwrite
// HIDE #include <stdio.h> FILE * fichier = ...; // SHOW double donnes[1000]; int lu = fread(donnes, sizeof (double), 1000, fichier); if (lu < 1000) { // Seulement "lu" doubles ont été lus }
// HIDE #include <stdio.h> FILE * fichier = ...; // SHOW int ecrit = fwrite(donnes, sizeof (double), 1000, fichier); if (ecrit != 1000) { // Erreur }
12
fseek, feof, ...
// HIDE #include <stdio.h> #include <inttypes.h> #include <arpa/inet.h> FILE * fichier = ...; // SHOW // Aller à la position 36 fseek(fichier, 36, SEEK_SET); // Lire un entier 32 bits (big endian) à cette position uint32_t beLength; int readInts = fread(&beLength, 4, 1, fichier); // Transformation big endian -> int sur notre système uint32_t length = ntohl(beLength); // Vérifier si on est à la fin du fichier if (feof(fichier)) return 1; // Vérifier s'il y a eu une erreur de lecture if (ferror(fichier)) return 1;
fseek
met la position de la prochaine lecture. feof
returne 1 si on est arrivé à la fin du fichier.13
5 min
Quand est-ce qu'on ne peut pas lire/écrire un fichier?
Qu'est-ce qu'il peut y avoir comme erreurs?
14
15
// HIDE #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> // SHOW int fd = open("mnt-suisse-romande", O_RDWR); if (fd == -1) { printf("Impossible d'ouvrir le fichier.\n"); return 1; } int longueur = 2501 * 3601 * sizeof(double); int type = PROT_READ | PROT_WRITE; double * altitudes = mmap(NULL, longueur, type, MAP_SHARED, fd, 0); close(fd); // Altitude est maintenant un tableau // Les changements sont écrites dans le fichier int altitude = altitudes[0]; altitudes[1] = 2000; ... // Libérer le tableau munmap(altitudes, longueur);
mmap
est disponible sous Linux (y compris Android), Mac OS et iOS. Sous Windows, il y a MapViewOfFile.
Pour créer un tableau read-only (verrouillé), remplacer O_RDWR par O_RDONLY, et enlever PROT_WRITE.
16
Lire un répertoire: opendir, readdir, closedir
// HIDE #include <stdio.h> #include <dirent.h> // SHOW DIR * repertoire = opendir("images"); if (repertoire == NULL) { printf("Impossible de lire le répertoire 'images'.\n"); return 1; } while (1) { struct dirent * fichier = readdir(repertoire); if (fichier == NULL) break; if (fichier->d_type == DT_REG) { printf("Fichier: %s\n", fichier->d_name); } else if (fichier->d_type == DT_DIR) { ... } } closedir(repertoire);
17
rename, unlink, stat
// HIDE #include <stdio.h> #include <unistd.h> #include <time.h> #include <sys/stat.h> // SHOW // Renommer un fichier (mv image.jpg photo.jpg) rename("image.jpg", "photo.jpg"); // Effacer un fichier (rm image.jpg) unlink("image.jpg"); // Informations sur un fichier (ls -l, stat image.jpg) struct stat info; int erreur = stat("image.jpg", &info); if (erreur) ...; printf("Taille: %0.2f MB\n", (double) info.st_size / 1000 / 1000); printf("Dernière modification: %s", ctime(&info.st_mtime));
Autres: link, symlink, readlink, (f)chmod, (f)chown
18