Algorithmique et langage C
Les entrées / sorties Les bases
Entrée / Sortie… même combat! previously in algorithmic Entrée / Sortie… même combat! Une entrée / sortie est un flot (fichier par exemple). Un flot est composé : d’une suite d’octet (le contenu du fichier). d’une tête de lecture. de booléen renseignant sur le dépassement fichier. NB:Les entrée / sorties standard (stdin, stdout et stderr) sont des flots définit du début à la fin du processus. en C on défini un flot (stream en anglais) mon_fichier comme suit FILE * mon_fichier; Ces flots sont soit accéder en lecture en écriture en écriture / lecture
fonction d’ouverture d’un fichier FILE * fopen ( const char * filename, const char * mode ); ou filename est le nom du fichier. Avec mode : r read Ouvrir un fichier existant pour lecture sur erreur retourne NULL w write Écraser le fichier existant et créer un nouveau fichier vide pour écriture sur erreur retourne NULL a append Ouvrir un fichier existant pour écriture, s’il n’existe pas créer un nouveau fichier vide et adresser la tête de lecture à la fin du fichier sur erreur retourne NULL
fonction d’ouverture d’un fichier Sous mode : b mode binaire (sinon mode ASCII) Applicable uniquement sur les modes et sous modes déclaré à gauche de lui + ouvrir dans le mode lecture/écriture manquant Le fichier est ouvert en lecture/écriture Donc, si je veux ouvrir un fichier appeler C:\titi\test.txt en mode lecture binaire et écriture ASCII et le mettre dans mon flot mon_fichier précédement déclaré, je fais mon_fichier=fopen("c:\\titi\\test.txt","rb+"); Si j’avais voulu la sortie en binaire aussi, j’aurais fait r+b
fonction de fermeture et fin du flot int fclose ( FILE * stream ); Retourne zéro si tout c’est bien passé, EOF sinon Donc dans notre cas du flot mon_fichier, on fera : fclose( mon_fichier ); int feof ( FILE * stream ); Retourne zéro si la fin de fichier n’est pas atteinte, sinon renvoi différent de zéro.
Au total pour bien utiliser un flot //déclaration du flot FILE * mon_fichier; //ouverture du flot mon_fichier=fopen("c:\\titi\\test.txt","rb+"); //traitement du flot (lecture, écriture, voir la suite) … //fermeture du flot fclose(mon_fichier);
fonction simple de lecture d’un flot Lecture d’un caractère char fgetc(FILE *stream); Retourne le caractère lu si tout c’est bien passé, EOF sinon Lecture d’une ligne (ou num caractères) char * fgets(char * str, int num, FILE * stream); Met dans le contenu pointé par str : les num premiers caractères du flot s’il ne rencontre pas de fin de ligne ou de fin de fichier (EOF = end of file), auquel cas il s’arrête et retourne le pointeur str. Lecture de x octets size_t fread(void *destination, size_t size, size_t number, FILE *stream); lit les size*number octets de stream et les met dans destination.
fonction simple d’écriture d’un flot écriture d’un caractère char fputc(char c, FILE *stream); Retourne le caractère lu si tout c’est bien passé, EOF sinon écriture d’une chaine de caractère int fputs(const char * str, FILE * stream); Écrit les caractères à partir de l’adresse str jusqu’au prochain caractère ‘\0’ soit le caractère nul. Retourne une valeur non négative si succès, EOF sinon. Écriture de x octets Size_t fwrite(const void *source, size_t size, size_t number, FILE *stream); Écrit les size*number octets de source dans stream.
Les chaines de caractères Une chaine de caractère est soit un pointeur, soit un tableau, exemple : char * modifiable_string = "non modifiable value"; char lenght_fixe_string[ ] = "modifiable value"; char * const non_modifiable_string = "non modifiable value"; En fait en c, il positionne en fin de la chaîne un caractère signifiant la fin de la chaine, le caractère nul (à ne pas confondre avec le NULL des pointeurs) que l’on représente dans une chaîne par \0 (zéro) caractère de fin de chaîne Mais il existe aussi \" guillemet \\ barre oblique inverse (antislash) \a signal sonore (bip) \n retour à la ligne \t tabulation
fonction de lecture/écriture formatée int fprintf ( FILE * stream, const char * format, ... ); Lecture formatée int fscanf ( FILE * stream, const char * format, ... ); Le format est inclus ou extrait du flot stream, c’est un chaîne de caractère. les … représente la liste possible des variables à formater dans la chaine format. Il sont spécifié dans le format par le symbole % associé à des spécifieurs.
Les formats (%spécifieur) spécifieur sortie Exemple c un caractère c d or i entier décimal signé 392 e notation Scientifique (mantise/exposant) 3.9265e+2 E notation Scientifique (mantise/Exposant) 3.9265E+2 f Décimal à virgule flottante 392.65 g utiliser le plus petit de %e ou %f 392.65 G utiliser le plus petit de %E ou %f 392.65 o octal signé 610 s chaine de caractère sample u entier décimal non signé 7235 x entier hexadécimal non signé (minuscule) 7fa X entier hexadécimal non signé (majuscule) 7FA p adresse de pointeur B800:0000 % un % suivi d’un % écrira % dans le flot. %
Les formats de sortie, la précision la précision se rajoute entre le % et le spécifieur, il s’écrit de 2 différentes formes a ou a.b Ou a représente le nombre de caractère minimum affiché. Il peut être précédé d’un espace / d’un 0 (zéro) qui comblerons les espaces. Il peut être précédé (pour un numérique) d’un plus/espace et/ou d’un moins. Le b représente pour les réels : le nombre de chiffres après la virgule. pour les chaînes de caractère : le nombre de caractères affiché de la chaîne source.
Les formats de sortie en clair fprintf(mon_fichier,"j’ecris dans mon fichier\n"); float my_float = 12.56; fprintf(stdout,"my_float a pour valeur : %015f\n", my_float); fprintf(stdout,"my_float a pour valeur : % 15.2f\n", my_float); fprintf(stdout,"my_float a pour valeur : %+15.2f\n", my_float); char * my_string = "hello world!!! \0damned i will be not print"; fprintf(stdout,"%s\n", my_string); fprintf(stdout,"%c\n", my_string[19]); fprintf(stdout,"%15.3sas\n", &my_string[16]); Donne j’ecris dans mon fichier my_float a pour valeur : 00000012.560000 my_float a pour valeur : 12.56 my_float a pour valeur : +12.56 hello world!!! n damas
Les formats d’entrée en clair Soit mon_fichier2 ouvert en lecture contenant jean martin 40 abbou simbel 30 sidonie delos 20 char p_1[50],p_2[50], p_3[50]; while (1) { fscanf(mon_fichier2,"%s %s %s",p_1,p_2,p_3); if (feof(mon_fichier2)) break; fprintf(stdout,"prénom : %s\tnom : %s\tage : %s\n", p_1, p_2, p_3);} Produira dans stdout : prenom : jean nom : martin age : 40 prenom : abbou nom : simbel age : 30 prenom : sidonie nom : delos age : 20
Le positionnement dans le flot v1 long ftell(FILE * stream); qui retourne dans un long la position de la tête de lecture du fichier int fseek(FILE * stream, long offset, int origin); qui renvoi à l'offset demandé la tête de lecture du fichier en prenant comme origin : SEEK_SET = le début du fichier SEEK_CUR = la position courante (préférer alors ouvrir le fichier en mode binaire) SEEK_END = la fin du fichier (idem mode binaire)
Le positionnement dans le flot v2 int fgetpos(FILE * f, fpos_t * p_pos); met dans p_pos la position de la tête de lecture dans le fichier int fsetpos(FILE * f, const fpos_t * p_pos); met la tête de lecture à la p_pos position dans le fichier Et bien sûr la remise à zéro int rewind(FILE * stream); qui met la tête de lecture en début de fichier.