begin process at 2013 05 23 00:19:44
  Trouver un code source :
 
dans
 
Accueil > 

Tutoriels

 > 

Tutoriaux

 > Les E/S, Les Fichiers

Les E/S, Les Fichiers


 Information sur le tutoriel

Note :
Aucune note


 Description

Ouverture, fermeture d'une fichier. Les opérations de lecture écriture (par ligne , caractère, enregistrement, format) les déplacement .....

Tutorial

Les E/S, Les Fichiers

Plan

1 Introduction

2 Ouverture d'un Fichier (fopen)

3 Fermeture d'un Fichier (fclose)

4 Opérations d'Ecriture/Lecture

4.1 caractère par caractère (fgetc, fputc, getc, putc, putchar, getchar, ungetc)

4.2 par ligne (fgets, fputs, gets, puts)

4.3 par enregistrements (fread, fwrite)

4.4 par format (fscanf, scanf, fprintf, printf)

4.5 déplacement (fseek, ftell)

5 Autres Fonctions


1] Introduction


• La bibliothèque <stdio.h> offre des fonctions de manipulation

d'E/S (au-dessus de celles du système d'exploitation pour augmenter la

portabilité des programmes).

• Tout périphérique (clavier, écran, imprimante, …) est manipulé

comme un fichier.

• Un fichier est une suite d'octets, accessible :

– de manière séquentielle (i.e. octets lus l'un après l'autre)

– par accès direct ou aléatoire (i.e. accès à un octet précis)

3 fichiers pré-ouverts associés à la console (constantes dans <stdio.h>)

stdin (standard input) entrée standard (clavier), 0

stdout (standard output) sortie standard (écran), 1

stderr (standard error) sortie d'erreur standard (écran), 2

Redirections possibles à l'appel du programme : prog >out 2>err <in


Entrées/Sorties Bufferisées


Pour des raisons d'efficacité, l'accès à un fichier se fait par l'intermédiaire

d'un buffer (ou mémoire tampon) pour réduire le nombre d'accès aux

périphériques (disques, …)

La taille de ce buffer est de 512ø dans le cas d'un fichier physique.

Si le courant est coupé, on perd le contenu du buffer.

Il peut y avoir une désynchronisation entre le clavier et l'écran. En effet, les

caractères tapés ne sont mis dans ce buffer que lorsqu'un retour chariot

ou une fin de fichier est tapé (e.g. la fonction getchar).

On peut forcer le vidage du buffer avec le fonction fflush

int fflush(FILE * descFichier);

fflush(stdin); permet de vider le buffer d'entrée (ie ignore les caractères tapés)

autre solution while (getchar() != '\n') ;


Tout fichier est identifié uniquement par sa position dans

l'arborescente et par son nom.

Dans un programme, il sera identifié par un descripteur de

fichier i.e. un pointeur sur une structure FILE. Un élément de

type TYPE* est appelé un flot de caractères, flux ou stream.

Une structure FILE indique la position courante dans le buffer,

l'adresse du buffer, le nombre de caractères écrits ou restant à

lire, mode d'accès (lecture, écriture, …), …

Il existe 2 types de fichiers :

les fichiers textes : suite de caractères ASCII organisés en ligne (caractère linefeed

à la fin de la ligne) finie par le caractère EOF (end of file). Les caractères

de contrôle (retour à la ligne, …) sont interprétés.

les fichiers binaires : les caractères de contrôle ne sont pas interprétés.


Avant opération sur un fichier, il faut l'ouvrir (fopen)

(sauf stdin, stdout et stderr)

Puis faire opérations:

• écriture/lecture caractère par caractère (getchar, putchar,

getc, putc, fgetc, fputc, ungetc)

• écriture/lecture par ligne (gets, fgets, puts, fputs)

• écriture/lecture par enregistrements (fwrite, fread)

• écriture/lecture formatées (printf, fprintf, scanf, fscanf)

• déplacement dans le fichier (fseek, ftell)

Puis le fermer (fclose)

2] Ouverture d'un fichier


FILE * fopen(const char * nomFichierAOuvrir,

const * char mode);

nomFichierAOuvrir : chaîne référençant dans l'arborescence le fichier à ouvrir.

mode : chaîne spécifiant le type d'ouverture. Par défaut le fichier est de type

texte i.e. contenant des caractères ASCII.

"r" en lecture

"w" en écriture (si le fichier existe, on écrase son contenu sinon on le crée)

"a" en ajout (si le fichier existe, on ajoute à la fin du fichier, sinon on le crée).

Possibilités de suffixes :

"b" fichier en mode binaire (données transférées sans interprétation)

"+" ouvert en mode complémentaire du mode de base (e.g. "r+" ouvert en

lecture/écriture).

Retourne un descripteur de fichier (égal à NULL s'il y a eu une erreur e.g.

le fichier n'existe pas, problème de droits d'accès ou FOPEN_MAX fichiers

sont déjà ouverts).

3] Fermeture de Fichier


int fclose(FILE * descFichierAFermer);

Détruit le lien entre le descripteur de fichier et le fichier physique.

Provoque l'écriture des données du buffer en cas de fichier ouvert

en mode écriture.

descFichierAFermer : descripteur du fichier à fermer.

Retourne EOF en cas d'erreur, sinon 0.

Exemple

#include <stdio.h>

void main() {

FILE * descFich;

descFich = fopen("tp1/morpion.c", "r");

if (descFich != NULL) {

….

fclose(descFich);

}

}

4.1] Lecture/Ecriture Caractère par Caractère


int fgetc(FILE * descFichierALire);

Retourne le caractère lu (de type unsigned char) dans le fichier associé ou

EOF si on est à la fin du fichier ou s'il y a eu une erreur.

int getchar(void); int fgetc(stdin); int getc(stdin); (!!!macro)

int fputc(int caracAEcrire, FILE * descFichierOuEcrire);

Ecrit le caractère donné (de type unsigned char) dans le fichier.

Retourne EOF en cas d'erreur ou la valeur du caractère écrit mise en entier.

int putchar(int); int fputc(int, stdout); int putc(int, stdout); (!!!macro)

int ungetc(int caracARemettre, FILE * descFichier);

Remet le caractère lu (sauf EOF) dans le flot de caractères.

Retourne EOF en cas d'erreur ou la valeur du caractère remis.



#include <stdio.h>

/* Affiche le contenu du fichier passé en paramètre */

void main(int argc, char * argv[]) {

if (argc > 1) {

FILE * pFile = fopen(argv[1], "r"); /* ouverture du fichier */

if (pFile != NULL) {

char car;

while ((car = fgetc(pFile)) != EOF) { /* lecture des caractères */

fputc(car, stdout); /* ou putchar(car) ou putc(car, stdout) */

}

fclose(pFile); /* fermeture */

} else

fprintf(stderr, "Impossible d'ouvrir le fichier %s", argv[1]);

} else

fprintf(stderr, "Veuillez donner le nom du fichier à afficher\n");

}

4.2] Lecture/Ecriture par Lignes


char * fgets(char * ouMettreLesCaracteresLus, int

tailleZoneOuMettreCarac, FILE * descFichierALire);

Lit les caractères (qui sont mis dans la zone mémoire pointée par

ouMettreLesCaracteresLus) jusqu'au caractère de fin de ligne inclus, la

fin de fichier ou jusqu'à (tailleZoneOuMettreCarac -1) caractères lus.

fgets rajoute le caractère NULL, '\0', à la fin des caractères lus.

Retourne le pointeur ouMettreLesCaracteresLus ou NULL si on est à la

fin du fichier ou s'il y a eu une erreur.

fgets(char*, int, stdin); ~ char* gets(char* ouMettreLesCaracteresLus);

Attention, gets ne contrôle pas le nombre de caractères mis dans la zone de

mémoire (d'où possibilité de débordement mémoire).

De plus, le caractère de fin de ligne est transformé en caractère de fin de

chaîne.


int fputs(const char * chaineAEcrire,

FILE * descFichierOuEcrire);

Ecrit la chaîne donnée dans le flux.

Retourne EOF en cas d'erreur sinon une valeur positive.

fputs(const char*, stdout); ~ int puts(const char * chaineAEcrire);

puts rajoute automatiquement le caractère de fin de ligne après l'écriture

de la chaîne donnée (≠ fputs).

char chaine[MAX];

while (fgets(chaine, MAX, pFile) != NULL) {

fputs(chaine, stdout);

}

4.3] Lecture/Ecriture par Enregistrements


Pour les Structures ou des données de grande taille (fichier binaire)

size_t fread(void * zone, size_t taille, size_t nombre, FILE* stream);

size_t fread(void * zone, size_t taille, size_t nombre, FILE* stream);

zone : adresse de début de la zone de mémoire où mettre/lire les données (de

taille au moins égale à taille*nombre)

taille : taille d'un enregistrement (en nombre d'octets)

nombre : nombre d'enregistrements à transférer

stream : descripteur de fichier ouvert en mode de transfert binaire

Retourne le nombre d'enregistrements lus/écrits

eg fread(&pers1, sizeof Personne, 1, pFich);

Fonctions permettant de transférer des données sans transcodage. Mais les

fichiers produits ne sont pas portables. Ces fonctions sont utiles pour

manipuler des données de grande taille ou des structures.

4.4] Lecture/Ecriture Formatées


int fscanf(FILE * ouLire, const char * chaineDeFormat, …);

int fscanf(stdin, const char*, …); int scanf(const char*, …);

Lit les données du flux en fonction des spécifications de format données

dans chaineDeFormat et affecte les valeurs converties aux arguments

donnés (qui sont des pointeurs, des adresses de variable).

Retourne EOF en cas de fin de fichier atteinte ou s'il y a eu une erreur de

conversion pour la première valeur, sinon elle retourne le nombre de

valeurs converties et affectées.

La chaineDeFormat peut contenir:

• des caractères d'espace ou de tabulation (ces caractères sont vus comme

des séparateurs ainsi que le retour chariot, saut de page ou fin de ligne),

• des caractères ordinaires (sauf %, espace ou tabulation) indiquant qu'ils

devront être présents dans les données lues,

• des spécifications de format/conversion (ou séquences d'échappement) de

la forme %[*][taille][infoTaille] Type. A chaque spécification correspond à

un argument (i.e une adresse de variable qui stockera la valeur lue et

convertie).


Description des spécifications de conversion


* (optionnel) indique que la donnée lue ne sera pas affectée à un argument mais

jetée.

– taille (optionnel) : nombre de caractères à lire, entier en base 10

– infoTaille (optionnel) : l (long), L (long) ou h (short)

– type

d entier signé exprimé en base 10; int*

i entier signé (en octal si commence par 0, en hexa si 0x ou 0X, en décimal sinon); int *

o entier sous forme octale; int*

u entier non signé exprimé en base 10; unsigned int*

x entier sous forme hexa (précédé ou non de 0x ou 0X); int*

e, f ou g nombre en virgule flottante (avec ou sans exposant E ou e); float*

c caractère; char*

s chaîne de caractère sans espace, tabulation ou retour chariot, avec le caractère '\0' à la

fin; char* (tableau ou zone mémoire de taille suffisant grand pour contenir la chaîne

entrée). Il faut utiliser fgets si on veut lire les espaces.

p adresse (l'inverse de printf("%p", pTab);); void*

n écrit dans l'argument le nombre de caractères lus

[...] chaîne de caractères parmi un alphabet; char * (si [^…] caractères n'appartenant pas)


int fprintf(FILE * ouEcrire, const char * chaineDeFormat, …);

int fprintf(stdout, const char*, …); int printf(const char*, …);

Ecrit les données dans le flux en fonction des spécifications de format

contenues dans chaineDeFormat.

Retourne le nombre de caractères écrits ou une valeur négative en cas

d'erreur.

La chaineDeFormat peut contenir:

• des caractères

• des spécifications de conversion de la forme

%[indicateurs][taille][.précision][infoTaille] Type

Description des spécifications de conversion

– indicateurs (optionnels) :

- indique que le résultat est à justifier à gauche

+ imprime le signe du nombre

0 complète le début du champs par des 0

# spécifie un format de sortie diffèrent (pour un octal, ajoutera 0 devant; 0x pour un hexa, …)

– taille (optionnel) : nombre minimal de caractères à écrire, entier en base 10


Description des spécifications de conversion (suite)

– précision (optionnel) : nombre max de caractères ou de chiffres à droite du

point d'un nombre flottant ou le nombre min de chiffres pour un entier.

– infoTaille (optionnel) : l (long), L (long) ou h (short)

– type

d, i notation décimale signée; int

o notation octale non signée (non précédée d'un 0) ; int

u notation décimale non signée; unsigned int

x, X notation hexa non signée(non précédée de 0x ou 0X); int

f notation décimale de la forme [-]mmm.dddddd où le nombre de d est donné

par la précision (par défaut, égal à 6); double

e, E notation decimale de la forme [-]m.dddddde±xx ou [-]m.ddddddE±xx où le

nombre de d est donné par la précision (par défaut, égal à 6); double

g, G impression selon %e si l'exposant est inférieur à -4 ou supérieur ou égal à la

précision, sinon comme %f; double

c caractère (converti en unsigned char) ; int

s chaîne de caractère imprimée jusqu'au '\0' ou selon la précision; char *

p adresse; void*

n le nombre de caractères écrits


#include <stdio.h>

#define MAX 100

void main(int argc, char * argv[]) {

if (argc > 1) {

FILE * pFile = fopen(argv[1], "w");

if (pFile != NULL) {

char nomProduit[MAX];

int idProd;

while (scanf("%d %s", &idProd, nomProduit) != EOF)

fprintf(pFile, "|%6d|%20s|\n", idProd, nomProduit);

fclose(pFile);

} else

fprintf(stderr, "Impossible d'ouvrir le fichier %s", argv[1]);

} else

fprintf(stderr, "Veuillez donner le nom du fichier où on écrit\n");

}


Exemple de fichier produit

| 12| imprimante|

| 23| chaise|

| 2345| ordi|


4.5] Déplacement dans un Fichier


int fseek(FILE * descFichier, long offset, int pointDeDepart);

Change la position courante dans le stream

offset : nombre d'octets dont on veut se déplacer (long positif ou négatif)

pointDeDepart :

• SEEK_SET (à partir du début du fichier)

• SEEK_CUR (à partir de la position courante)

• SEEK_END (à partir de la fin du fichier)

Retourne une valeur différente de 0 si erreur, 0 sinon

int ftell(FILE * descFichier);

Retourne la valeur de la position courante (-1 en cas d'erreur)

Utile pour memoriser une position pour s'y repositionner ultérieurement

Pour connaître la taille d'un fichier : fseek(pFich, 0L, SEEK_END);

longueur = ftell(pFich);


5] Autres Fonctions


int remove(const char * nomFichierADetruire);

Pour détruire un fichier. Retourne une valeur différente de 0 si échec.

int rename(const char * nomFichierARenommer, const char*nouveauNom);

Pour renommer un fichier.

int feof(FILE * stream);

Test si la marque de fin de fichier a été lue (pour savoir si erreur ou EOF pour getc)

int ferror(FILE * stream);

Retourne une valeur non nulle si une erreur s'est produite

void perror(const char* chaine);

Imprime chaîne et un message d'erreur correspondant à l'entier contenu dans errno.

int sprintf(char *s, const char * format, …);

int sscanf(char *s, const char * format, …);

Comme printf et scanf mais pour un tableau.


Thebroyeur

Commentaires

Commentaire de gregroar le 16/06/2010 12:09:18

excellent.
Ça faisait un moment que je cherchais un bon tuto comme celui la sur les entrées sorties sur les fichiers.
Je cherche à travailler sur un dictionnaire de 30 à 50 Mo, qui pourrait bien devenir un fichier texte de plusieurs centaines de Mo.
Et c'est tellement gros, j'arrive pas, vient un moment ou ça plante.
Je pense que ton tuto va m'aider.
Est ce plus rapide de travailler sur 26 plus petits fichiers ou un gros va très bien? C'est que tout le fichier est parcouru du début à la fin non?

Commentaire de selkanesalim le 02/08/2010 18:25:38

Exellent tuto merci beaucoup....

Commentaire de arwinho1988 le 07/11/2010 14:26:20

good tuto,ça m'a bcp aide ds mon projet d'annuaire telephonnik!!!

Commentaire de Eneur le 11/11/2010 09:26:04

Merci beaucoup pour cet excellent résumé; il va me permettre de modifier certains de mes petits programmes. Merci

Commentaire de florianh le 06/12/2010 14:50:34

Excellent tutoriel !
Détaillé, vaste (manque peut-être quelques infos sur où aller chercher les fichier pour ecran, imprimante, et autres cités en introductions).
Merci beaucoup, je le conseil d'ailleurs à un amis qui débute.

Commentaire de abuohknay le 21/12/2010 14:37:01

Bonjour Messieurs
Je suis un vieux informaticien de 55 ans et passionné par mon métier. Maitrisant plus clipper, le COBOL, RPG II IBM,DBASE IV. Ces derniers temps j'ai décidé d'apprendre le C++. Je suis à fond je vois des choses inespérées. Mais jusqu'à présent je n'ai pas atteint, si ça existe, le tuto parlant des base de données ce tuto que vous avez fait me montre que cela devrait exister quelque part dans le monde virtuel. Alors au secours pour cette utilisation car tous les logiciels que j'ai eu à écrire sont traduit en clipper dos au préalable écrit en COBOL HP3000 pour vous dire. Si un tutoriel gratuit existe dites le moi mon email est yankyamadiallo@yahoo.fr.
Merci à tous.

Commentaire de djelloulinfo le 11/10/2011 11:36:28

Merci beaucoup

Commentaire de Menelag le 19/04/2013 06:33:55

excellent tuto, merci

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2013
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Photothèque

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,328 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales