Traducteur mot à mot



Documents pareils
Cours 6 : Tubes anonymes et nommés

Programmation système de commandes en C

3IS - Système d'exploitation linux - Programmation système

TRAVAUX PRATIQUES Programmation Système Langage C / Système UNIX. 2 e année Génie Informatique

Le prototype de la fonction main()

GESTION DES FICHIERS C/UNIX

Programmation système en C/C++

Les processus. Système L3, /39

Le système de gestion des fichiers, les entrées/sorties.

Cours Programmation Système

Programmation système I Les entrées/sorties

École Polytechnique de Montréal. Département de Génie Informatique et Génie Logiciel. Cours INF2610. Contrôle périodique.

I. Introduction aux fonctions : les fonctions standards

Le langage C. Séance n 4

Cours de C. Allocation dynamique. Sébastien Paumier

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

Compression de Données - Algorithme de Huffman Document de Conception

Dans le chapitre 1, nous associions aux fichiers ouverts des descripteurs de fichiers par lesquels nous accédions aux fichiers.

Simulation d un système de paiement par carte bancaire

Programmation Système (en C sous linux) Rémy Malgouyres LIMOS UMR 6158, IUT département info Université Clermont 1, B.P.

Cours de Système : Gestion de Fichiers

Archivage Messagerie Evolution pour usage HTML en utilisant Hypermail

MISE A NIVEAU INFORMATIQUE LANGAGE C - EXEMPLES DE PROGRAMMES. Université Paris Dauphine IUP Génie Mathématique et Informatique 2 ème année

Cours 14 Les fichiers

DNS Server RPC Interface buffer overflow. Céline COLLUMEAU Nicolas BODIN

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

Les structures de données. Rajae El Ouazzani

Qu'est-ce qu'un processus: Définitions

Arguments d un programme

Comment développer et intégrer un module à PhpMyLab?

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

Programmation impérative

LEs processus coopèrent souvent pour traiter un même problème. Ces

Conventions d écriture et outils de mise au point

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Chapitre 1 : La gestion dynamique de la mémoire

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Processus! programme. DIMA, Systèmes Centralisés (Ph. Mauran) " Processus = suite d'actions = suite d'états obtenus = trace

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Les structures. Chapitre 3

Java Licence Professionnelle CISII,

Les fichiers. Chapitre 4

Communication par sockets

Programmation C++ (débutant)/instructions for, while et do...while

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Introduction aux Systèmes et aux Réseaux

AWS avancé. Surveiller votre utilisation d EC2

Architecture d un système d exploitation

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Cours de C. Petits secrets du C & programmation avancée. Sébastien Paumier

OS Réseaux et Programmation Système - C5

Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles florence.henry@obspm.fr

Gestion des fichiers. Telecom-ParisTech BCI Informatique

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

#include <stdio.h> #include <stdlib.h> struct cell { int clef; struct cell *suiv; };

Algorithmique et Programmation, IMA

Gestion de la mémoire

Cours d initiation à la programmation en C++ Johann Cuenin

Compte-rendu de projet de Système de gestion de base de données

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Introduction à la Programmation Parallèle: MPI

Initiation à la programmation en Python

TP2 : tableaux dynamiques et listes chaînées

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Recherche dans un tableau

Lier Erlang avec d autres langages de programmation

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Les chaînes de caractères

Programmation en langage C Eléments de syntaxe

TP : Shell Scripts. 1 Remarque générale. 2 Mise en jambe. 3 Avec des si. Systèmes et scripts

INF 104 (SELC) Introduction au langage C

INTRODUCTION AUX SYSTEMES D EXPLOITATION. TD2 Exclusion mutuelle / Sémaphores

La programmation des PIC en C. Les fonctions, les interruptions.


Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

Programmation système

Programmation Objet - Cours II

Les processus légers : threads. Système L3, /31

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Langage C. Patrick Corde. 22 juin Patrick Corde ( Patrick.Corde@idris.fr ) Langage C 22 juin / 289

Cours Langage C/C++ Programmation modulaire

Introduction au langage C

Applications client/serveur TCP/IP - Sockets Rappels. C.Crochepeyre Applications CS 1

INF2015 Développement de logiciels dans un environnement Agile. Examen intra 20 février :30 à 20:30

Les débordements de tampons et les vulnérabilités de chaîne de format 1

REALISATION d'un. ORDONNANCEUR à ECHEANCES

Programmation C. Apprendre à développer des programmes simples dans le langage C

Manuel d'installation

Derrière toi Une machine virtuelle!

Outils pour la pratique

Programmation défensive

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Unix : Programmation Système

Programmation en langage C

TP : Gestion d une image au format PGM

1. Structure d'un programme FORTRAN 95

Transcription:

Traducteur mot à mot CORRECTION Ce document, ainsi que le programme C et un exemple de programme trad-fr-us, peut être trouvé en ligne à l'addresse suivante : http ://www.lifl.fr/hauspie/hauspie/teaching. Exercice 1 : Traducteur mot à mot (15 points) Vous apporterez un soin particulier à la libération de la mémoire allouée ainsi qu'à la gestion des erreurs éventuelles des fonctions systèmes Le but de cet exercice est d'écrire un traducteur de texte naïf. La traduction d'un texte d'une langue à une autre sera faite mot à mot. Pour cela, nous disposons de plusieurs programmes permettant de traduire un mot dans une langue donnée. Par exemple, nous pouvons avoir à disposition les programmes suivants : Programme Langue d'origine Langue de destination trad-us-fr Anglais US Français trad-fr-us Français Anglais US trad-de-fr Allemand Français trad-fr-de Français Allemand Ces programmes lisent un mot sur leur entrée standard et sortent la traduction sur leur sortie standard. Voici deux exemples d'utilisation d'un de ces programmes : hauspie@barbar:~/$./trad-us-fr chair ^D chaise hauspie@barbar:~/$ echo "Ordinateur"./trad-FR-US computer hauspie@barbar:~/$ Q 1. Écrire une fonction : char *traduire_mot(const char *mot, const char *langue_source, const char *langue_destination); qui prend un mot, une langue source et une langue destination en paramètre et qui retourne la traduction du mot (vous ferez attention à la validité du pointeur que retourne la fonction). La chaîne de caractère représentant une langue sera telle que décrite dans le tableau précédent (par exemple "US" pour la langue anglaise, "FR" pour la langue française). Cette fonction est chargée de créer deux tubes : un tube pour envoyer le mot à traduire; un autre tube pour récupérer le résultat de la traduction. Une fois les deux tubes créés, le processus père doit créer un processus ls qui eectuera les redirections nécessaires et exécutera la commande permettant d'eectuer la traduction dans la langue désirée. Le processus père lira alors le résultat de la traduction dans le tube et attendra la mort de son ls. Le mot traduit sera ensuite retourné par la fonction. Le schéma ci-dessous illustre la communication père-ls : Q 2. Écrire une fonction : int traduire_fichier(int source, int destination, const char *langue_source, const char *langue_destination); qui traduit le texte lu sur le descripteur source et envoyer la traduction sur le descripteur destination. La traduction sera faite mot à mot. La fonction retournera le nombre de mot traduits si tout s'est bien passé ou -1 s'il y a eu une erreur. On rapelle que la fonction isspace permet de tester si un caractère est un caractère de séparation (espace, tabulation...). Q 3. Écrire maintenant le main de votre programme qui devra supporter les options suivantes et appeler les fonctions précédentes pour eectuer le traitement :

-i chier_source Donne le nom du chier à traduire. Si cette option n'est pas présente sur la ligne de commande, votre programme devra traduire le texte qu'il lira sur son entrée standard. -o chier_destination Donne le nom du chier destination. Si cette option n'est pas présente sur la ligne de commande, votre programme devra produire la traduction sur la sortie standard. -il langue_source Précise la langue source. Si cette option n'est pas présente sur la ligne de commande, votre programme doit utiliser la langue "US". -ol langue_destination Précise la langue destination. Si cette option n'est pas présente sur la ligne de commande, votre programme doit utiliser la langue "FR". Une fois la traduction eectuée, votre programme doit acher un message indiquant à l'utilisateur le nombre de mots traduits. 1 #include <stdio.h> 2 #include <unistd.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <ctype.h> 6 #include <sys/types.h> 7 #include <sys/wait.h> 8 #include <sys/stat.h> 9 #include <fcntl.h> 10 11 #define TAILLE_BUFFER 1024 /* 1ko de buffer pour lire dans le fichier */ 12 #define TAILLE_MAX_MOT 64 /* mot de 64 carac max... devrait etre 13 * suffisant... On va faire les tests mais on va 14 * tronquer pour ne pas allourdir le code */ 15 16 char *traduire_mot(const char *mot, const char *src_lg, const char *dst_lg) 17 { 18 /* les descripteurs pour les deux tubes. Les noms sont donnée point de vue 19 du processus père. on envoie le mot a traduire dans emission et on 20 recoit le mot traduit dans reception 21 */ 22 int emission[2]; 23 int reception[2]; 24 int pid; 25 26 /* création du premier tube */ 27 if (pipe(emission) == -1) 28 { 29 perror("creation du premier tube"); 30 return NULL; 31 } 32 33 /* création du deuxième tube */ 34 if (pipe(reception) == -1) 35 { 36 perror("creation du deuxieme tube"); 37 return NULL; 38 } 39 40 /* Création du processus fils */ 41 pid = fork(); 42 43 if (pid == 0) 44 { 45 char nom_commande[64]; /* 64 caractères sont amplement suffisants */ 46 /* dans le fils */ 47 /* on a pas besoin de l'entree du tube d'emission et de la sortie du tube 48 * de reception */ 49 close(emission[1]); 50 close(reception[0]); 51 52 /* redirection des e/s */ 53 close(0); /* on ferme l'entrée standard */ 54 dup(emission[0]); /* on redirige l'entrée standard i.e. read(0,...) 55 * devient équivalent à read(emission[0],...) */ 56 close(emission[0]); /* on a plus besoin du descripteur emission[0] car le 57 * descripteur 0 "pointe" sur la sortie du tube */ 58

59 close(1); /* on ferme la sortie standard */ 60 dup(reception[1]); /* on redirige la sortie standard i.e. write(1,...) 61 * devient équivalent à write(reception[1],...) */ 62 close(reception[1]); /* on a plus besoin du descripteur reception[1] car 63 * le descripteur 1 "pointe" sur l'entrée du tube */ 64 65 /* la redirection des entrées/sorties est effectuée, on peut lancer le 66 * programme */ 67 /* il faut construire son nom. Ce nom est consitué du mot "trad" suivi de 68 * "-", src_lg, "-" puis enfin dst_lg. */ 69 70 strcpy(nom_commande, "./trad-"); 71 strcat(nom_commande, src_lg); 72 strcat(nom_commande, "-"); 73 strcat(nom_commande, dst_lg); 74 75 /* le nom de la commande est construit, on a plus qu'a l'executer */ 76 /* on utilise execlp car il est plus adapté a notre cas (on ne passe pas 77 * de paramètre à la commande) */ 78 execlp(nom_commande, nom_commande, NULL); 79 /* si on arrive ici dans le programme, c'est qu'il y a eu un probleme avec execlp */ 80 perror("execution de la commande"); 81 exit(1); /* on quitte le processus fils */ 82 } 83 else 84 { 85 /* pointeur vers le mot traduit, on va allouer l'espace un peu plus 86 * bas... */ 87 char *mot_traduit = NULL; 88 int nb_caracteres_lus = 0; 89 int status; 90 /* dans le père */ 91 /* on a pas besoin de emission[0] ni de reception[1] */ 92 close(emission[0]); 93 close(reception[1]); 94 95 /* on envoie le mot à traduire sur le tube d'emission */ 96 if (write(emission[1], mot, strlen(mot)) < 0) 97 { 98 perror("erreur à l'écriture dans le tube"); 99 /* on va quitter donc il faut tout fermer proprement */ 100 close(emission[1]); 101 close(reception[0]); 102 wait(&status); /* on attends la fin du fils */ 103 return NULL; /* traduction impossible, on retourne null */ 104 } 105 106 /* on ferme le descripteur d'emission */ 107 close(emission[1]); 108 109 /* on alloue de l'espace pour obtenir la réponse... 64 caractères 110 * devraient être suffisant pour tous les mots :) */ 111 mot_traduit = (char *) malloc(64*sizeof(char)); 112 113 if ( (nb_caracteres_lus = read(reception[0], mot_traduit, 63)) < 0) 114 { 115 /* probleme à la lecture... */ 116 perror("probleme à la lecture dans le tube"); 117 /* on va quitter donc il faut tout fermer proprement */ 118 close(emission[1]); 119 close(reception[0]); 120 wait(&status); /* on attends la fin du fils */ 121 free(mot_traduit); /* on oublie pas de désallouer ce qu'on a alloué */ 122 return NULL; /* traduction impossible, on retourne null */ 123 } 124 125 mot_traduit[nb_caracteres_lus] = '\0'; /* on s'assure de la présence du 126 * '\0' à la fin pour construire 127 * une chaine valide */ 128 /* on ferme les descripteurs dont on a plus besoin */

129 close(reception[0]); 130 /* on attends la fin du fils */ 131 wait(&status); 132 /* le fils est fini, on peut renvoyer le mot traduit. Comme il est dans 133 * un espace alloué par malloc(), la fonction appelante pourra s'en 134 * servir. Ce sera à cette fonction de désallouer la mémoire quand elle 135 * n'en aura plus besoin */ 136 return mot_traduit; 137 } 138 /* on arrivera jamais ici... le return est seulement la pour que le 139 * compilateur soit content */ 140 return NULL; 141 } 142 143 144 int traduire_fichier(int fichier_source, int fichier_destination, const char *langue_source, const char *langue_dest 145 { 146 /* comme on ne connait pas la taille du fichier à ouvrir, il va falloir lire 147 * par petit morceaux... */ 148 149 char buffer[taille_buffer]; /* Buffer pour lire dans le fichier */ 150 char mot_courant[taille_max_mot]; /* va servir à écrire le mot courant. */ 151 int nb_carac_lus = 0; /* nombre de caractères lus */ 152 int nb_mot_traduits = 0; 153 char *ptr_mot = mot_courant; 154 155 mot_courant[0] = '\0'; /* on initialise la chaine à une chaine vide */ 156 157 while ((nb_carac_lus = read(fichier_source, buffer, 1024)) > 0) 158 { 159 char *lettre = buffer; 160 161 while (nb_carac_lus > 0) 162 { 163 if (isspace(*lettre)) /* on a un espace */ 164 { 165 if (*mot_courant!= '\0') /* on a construit un mot */ 166 { 167 char *mot_traduit = NULL; 168 *ptr_mot = '\0'; /* on termine la chaine du mot à traduire */ 169 /* on lance la traduction du mot */ 170 mot_traduit = traduire_mot(mot_courant, langue_source, langue_destination); 171 if (mot_traduit!= NULL) /* la traduction s'est effectuée correctement */ 172 { 173 /* on ecrit le mot dans le fichier destination*/ 174 if (write(fichier_destination, mot_traduit, strlen(mot_traduit)) < 0) 175 { 176 perror("probleme d'écriture fichier destination"); 177 free(mot_traduit); /* on libere la mémoire allouée par traduire_mot */ 178 return -1; 179 } 180 else 181 { 182 nb_mot_traduits++; 183 } 184 } 185 free(mot_traduit); /* on libere la mémoire allouée par traduire_mot */ 186 ptr_mot = mot_courant; 187 } 188 /* on écrit le caractere espace dans le fichier destination... */ 189 if (write(fichier_destination, lettre, 1) <= 0) 190 { 191 perror("probleme d'écriture fichier destination (espace)"); 192 return -1; 193 } 194 lettre++; 195 } 196 else if ((ptr_mot - mot_courant) < TAILLE_MAX_MOT-1) /* on écrit les 197 *caractères que si on ne depasse pas la taille de notre buffer, on 198 *tronquera si un mot de plus de 64 caractères apparait. Pas

199 *forcement la meilleure solution, mais elle est sûre et n'obscurcit 200 *pas le code. */ 201 *ptr_mot++ = *lettre++; /* *ptr++ = 'a' va affecter le caractere 'a' 202 *à la zone mémoire pointée par ptr PUIS incrémenter le pointeur */ 203 nb_carac_lus--; 204 } 205 } 206 if (nb_carac_lus!= 0) /* la lecture n'a pas fonctionnée */ 207 { 208 perror("probleme de lecture dans le fichier source"); 209 return -1; 210 } 211 return nb_mot_traduits; 212 } 213 214 int main(int argc, char **argv) 215 { 216 int fichier_source = 0; 217 int fichier_destination = 1; 218 char langue_source[32]; 219 char langue_destination[32]; 220 int i; 221 222 strcpy(langue_source, "FR"); 223 strcpy(langue_destination, "US"); 224 225 for (i = 1; i < argc-1 ; i+=2) 226 { 227 if (strcmp(argv[i], "-i") == 0) 228 { 229 /* ouverture d'un fichier source */ 230 fichier_source = open(argv[i+1], O_RDONLY); 231 if (fichier_source == -1) 232 { 233 perror("ouverture du fichier source"); 234 return 1; 235 } 236 } 237 else if (strcmp(argv[i], "-o") == 0) 238 { 239 /* ouverture d'un fichier destination */ 240 fichier_destination = open(argv[i+1], O_CREAT O_RDWR, 0755); 241 if (fichier_destination == -1) 242 { 243 perror("ouverture du fichier destination"); 244 return 1; 245 } 246 } 247 else if (strcmp(argv[i], "-il") == 0) 248 { 249 strcpy(langue_source, argv[i+1]); 250 } 251 else if (strcmp(argv[i], "-ol") == 0) 252 { 253 strcpy(langue_destination, argv[i+1]); 254 } 255 else 256 { 257 fprintf(stderr, "Mauvais parametre: %s\n", argv[i]); 258 } 259 } 260 261 262 i = traduire_fichier(fichier_source, fichier_destination, langue_source, langue_destination); 263 264 /* on ferme les fichiers dont on s'est servi */ 265 if (fichier_destination!= 1) 266 close(fichier_destination); 267 if (fichier_source!= 0) 268 close(fichier_source);

269 270 if (i == -1) 271 return 1; /* pas besoin d'afficher un message d'erreur, les fonctions précédentes s'en chargent */ 272 273 printf("traduction terminée, %d mot(s) traduit(s)\n", i); 274 return 0; 275 }