Langage C

Cours

Le cours au format PDF est disponible ici.

Exemples

hello1.c

#include <stdio.h>

int main()
{
   int a = 2;
   printf("%d est compris entre %d et %d.\n",a,1,3);
   return(0);
}

printf_ex.c

#include <stdio.h>

int main()
{
   printf("%d\n", 1);
   printf("%f\n",0.10);
   printf("%e\n",0.10);
   printf("%E\n",0.10);
   printf("%g\n",0.10);
   printf("%f\n",0.0000010);
   printf("%e\n",0.0000010);
   printf("%g\n",0.0000010);
   printf("%G\n",0.0000010);

   printf("|12345| |12345| |12345|\n");
   printf("|%5d| |%-5d| |%d|\n",1,1,1);
   printf("|%5d| |%-5d| |%d|\n",10,10,10);
   printf("|%5d| |%-5d| |% d|\n",-10,-10,-10);
   printf("|%+5d| |%-5d| |%+d|\n",10,10,10);
   printf("|%5d| |%-5d| |%d|\n",1000,1000,1000);
   printf("|%5d| |%-5d| |%d|\n",1000000,1000000,1000000);

   printf("%10.4f\n",123.456789);

   printf("|%s|\n","toto");
   printf("|%10s|\n","toto");
   printf("|%-10s|\n","toto");
   return(0);
}

hello4.c

#include <stdio.h>
int
main ()
{
  int a, b, c, d, result;

  a = 1;
  b = 1;
  c = 1;
  d = 1;
  result = a++;
  printf (" Resultat de a++ : %d %d\n", result,a);
  result = ++b;
  printf (" Resultat de ++b : %d %d\n", result,b);
  result = c--;
  printf (" Resultat de c-- : %d %d\n", result,c);
  result = --d;
  printf (" Resultat de --d : %d %d\n", result,d);
  return (0);
}

pointeur.c

#include <stdio.h>

int main()
{
   int m;
   int n;

   m = 0xa;
   n = -2;
   printf("m vaut %d, son adresse est %p\n", m, &m);
   printf("n vaut %d, son adresse est %p\n", n, &n);
   n = 226;
   printf("n vaut %d, son adresse est %p\n", n, &n);
   return(0);
}

affiche2.c

#include <stdio.h>

void affiche(int a, float y)
{
   printf("Taille d'un entier: %d, d'un flottant: %d\n", sizeof(int), sizeof(float));
   printf("Voici un entier : %d\n", a);
   printf("Voici un flottant : %f\n", y);
}

int add_entiers(int x, int y)
{
   int resultat;
   resultat = x+y;
   printf("addresse de x: %p\n", &x);
   printf("addresse de y: %p\n", &y);
   printf("addresse de resultat: %p\n", &resultat);
   printf("addresse de add_entiers: %p\n", &add_entiers);
   return(resultat);
}

affiche.c

#include <stdio.h>
#include "affiche.h"


int main()
{
   int a;
   int b;
   int c;

   a = 5;
   b = 7;
   printf("addresse de a: %p\n", &a);
   printf("addresse de b: %p\n", &b);
   printf("valeur de c: %d\n", c);
   printf("addresse de c: %p\n", &c);
   c = add_entiers(a, b);
#ifdef AFFICHE
   affiche(c,3.56);
#endif
#define AFFICHE
   a = add_entiers(c, a);
   return(0);
}

test5.c

#include <stdio.h>
#include <stdlib.h>


int main()
{
    int entier;        /* variable entiere */
    int *pointeur  = NULL;     /* pointeur sur un entier */

    entier = 5 ;

    printf(" entier = %d, son adresse est %p\n", entier, &entier);
    printf(" pointeur = %p, son adresse est %p\n",
             pointeur, &pointeur);

    pointeur = &entier; 

    printf(" pointeur = %p, son adresse est %p, il pointe sur %d\n",
             pointeur, &pointeur, *pointeur);

        *pointeur=10;
    printf(" entier = %d, son adresse est %p\n", entier, &entier);
    printf(" pointeur = %p, son adresse est %p, il pointe sur %d\n",
             pointeur, &pointeur, *pointeur);

   return(0);
}

euclidien.c

#include <stdio.h>

#include <stdlib.h>


void euclidien(int a, int b, int *qPtr, int *rPtr)
{
   *qPtr = a/b;
   *rPtr = a%b;
}

int main()
{
   int a, b, q, r;

   /* a/b -> (q, r) tel que a=b*q+r avec 0<= r < b */

   a = 199;
   b= 13;
   euclidien(a, b, &q, &r);
   printf("%d/%d = (%d, %d) \n", a, b, q, r);

   return(0);
}

test8.c

#include <stdio.h>

int main()
{
   int v = 278;
   int f = 399;
   printf("vrai: %d\n", v);
   printf("faux: %d\n", f);
   printf("vrai ou faux : v || f : %d\n", (f==0) || (v/f));
   printf("vrai et faux : v && f : %d\n", v && f);
   printf("non vrai     :   !v   : %d\n", !v);
   printf("non faux     :   !f   : %d\n", !f);
   return(0);
}

switch1.c

#include <stdio.h>

int main()
{
   int jour;

   jour = 1;
   switch (jour)
   {
      case 1:
         printf("%d : lundi\n",jour);
         break;
      case 2:
         printf("%d : mardi\n",jour);
         break;
      case 3:
         printf("%d : mercredi\n",jour);
         break;
      default:
         ;    /* instruction vide */
   }
   return(0);
}

ex_scanf.c

#include <stdio.h>

int main()
{
   int n;

   printf("Nombre : ");
   scanf("%d", &n);
   printf("Vous avez rentre: %d\n", n);
   return(0);
}

second_degre.c

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

double delta(double a, double b, double c)
{
   return (b*b-4.0*a*c);
}

void resolution(double a, double b, double c,
                int *nombre_solution, 
                double *solution1,
                double *solution2)
{
   double d;

   d = delta(a, b, c);
   if (d < 0.0)
   {
      *nombre_solution = 0;
   }
   else if (d == 0.0)
   {
      *nombre_solution = 1;
      *solution1 = (-b)/2.0/a;
   }
   else
   {
      *nombre_solution = 2;
      *solution1 = (-b-sqrt(d))/2.0/a;
      *solution2 = (-b+sqrt(d))/2.0/a;
   }
}

void affichage(int nombre_solution, double s1, double s2)
{
   switch (nombre_solution)
   {
      case 2:
    printf("Deux solutions: %f et %f\n", s1, s2);
        break;
      case 1:
    printf("Une solution: %f\n", s1);
        break;
      case 0:
    printf("Pas de solution\n");
        break;
      default:
    printf("Probleme dans la resolution !!!!\n");
        exit(1);
   }
}

int main()
{
   float t;
   double a, b, c;
   double solution1 = 0.0;
   double solution2 = 0.0;
   int nombre_solution = 0;

   printf("a: "); scanf("%f", &t); a = (double) t;
   printf("b: "); scanf("%f", &t); b = (double) t;
   printf("c: "); scanf("%f", &t); c = (double) t;

   resolution(a, b, c, &nombre_solution, &solution1, &solution2);
   affichage(nombre_solution, solution1, solution2);
   return(0);
}

chaine.c

#include <stdio.h>

int main()
{
   int i;
   double toto[10];
   char c;
   char chaine[] = "Bonjour\n otot \t toto";
   char chaine1[] = "toto";

   printf("Taille de toto (en octets): %d\n", sizeof(toto));
   printf("Taille de toto (en elements) : %d\n", sizeof(toto)/sizeof(double));
   printf("Taille de c: %d\n", sizeof(c));
   printf("%d: %s\n", sizeof(chaine), chaine);

   for (i = 0; i < sizeof(chaine)/sizeof(char); i++)
      printf("index %d, caractere %d, %c\n", i, chaine[i], chaine[i]);

   for (i = 0; i < sizeof(chaine1)/sizeof(char)-1; i++)
   {
      printf("%c", 'A'+(chaine1[i]-'a'));
   }
   printf("\n");

   return(0);
}

tab2.c

#include <stdio.h>
#include <stdlib.h>

int main()
{
   int n;
   int *ptrTab;
   int i;

   printf("Entrez la taille du tableau: ");
   scanf("%d", &n);

   ptrTab = (int *) malloc(n*sizeof(int));

   if (ptrTab == NULL)
   {
      printf("pas d'allocation de %d octets\n", n*sizeof(int));
      exit(1);
   }

   printf("adresse de ptrTab: %p\n", ptrTab);
   printf("adresse du premier element: %p\n", &(ptrTab[0])); 
   for (i = 0; i < n; i++) ptrTab[i] = 2*i-3;
   /*
   for (i = 0; i < n; i++) printf("ptrTab[%d] = %d\n", i, ptrTab[i]);
   */

   free(ptrTab);

   return(0);
}

tab.c

#include <stdio.h>

int main()
{
  int tab[5] = {1, 2, 3, 4, 5};

  printf("adresse de tab: %p\n", tab);
  printf("adresse de tab[0]: %p\n", &tab[0]);
  printf("adresse de tab[4]: %p\n", &tab[4]);
  printf("&tab[0]+4): %p\n", &tab[0]+4);
  printf("taille de tab: %d\n", sizeof(tab));
  printf("&tab[4]-&tab[0]: %d\n", &tab[4]-&tab[0]);
  printf("tab[2]: %d\n", tab[2]);
  printf("*(&tab[0]+2): %d\n", *(&tab[0]+2));
  printf("*(tab+2): %d\n", *(&tab[0]+2));
  return(0);
}

file1.c

#include <stdio.h>
#include <stdlib.h>

int main()
{
   FILE *pointeur_fichier = NULL;
   char nom_fichier[] = "hello1.c";
   char ligne;

   /* on ouvre le fichier */
   pointeur_fichier = (FILE *)fopen(nom_fichier, "r");
   /* on verifie qu'il est bien ouvert */
   if (pointeur_fichier == NULL)
   {
      printf("Erreur d'ouverture du fichier %s\n", nom_fichier);
      exit(1);
   }
   printf("fichier %s : \n", nom_fichier);
   /* lecture des caractères du fichier */
   printf("ftell: %d\n", ftell(pointeur_fichier));
   while ( fscanf(pointeur_fichier,"%c",&ligne) != EOF)
   {
      printf("%c",ligne);
   }
   /* fermeture du fichier */
   printf("ftell: %d\n", ftell(pointeur_fichier));
   fclose(pointeur_fichier);
   return(0);
}

test_fscanf.c

#include <stdio.h>
#include <stdlib.h>

int main()
{
   char *nom_fichier="texte";
   char chaine[1000000];
   FILE *fichier;

   fichier = (FILE *)fopen(nom_fichier, "r");
   if (fichier == NULL)
      exit(1);

/*
   while ( fgets(chaine, 1000000, fichier) != NULL)
*/
   while ( fscanf(fichier, "%s", chaine) != EOF)
   {
      printf("%s\n", chaine);
   }
   return(0);
}

test_strtok.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
   char *nom_fichier="test_strtok.c";
   char chaine[1000000];
   FILE *fichier;
   char *token;

   fichier = (FILE *)fopen(nom_fichier, "r");
   if (fichier == NULL)
      exit(1);

   while ( fgets(chaine, 1000000, fichier) != NULL)
   {
      token = strtok(chaine, ";");
      while (token != NULL)
      {
         printf("----------------------------\n");
         printf("%s\n", token);
         token = strtok(NULL, " \n.");
      }
   }
   return(0);
}

test_system.c

#include <stdio.h>

#include <stdlib.h>

int main()
{
   int ret;

   ret = system("grep printf test_system.c");
   printf("%d\n", ret);
   return(ret);
}

test_bsearch.c

#include <stdio.h>

#include <stdlib.h>

int compare(int *a, int *b)
{
   if (*a < *b)
   { return(-1); }
   else if (*a == *b)
   { return(0); }
   else 
   {/*if (*a > *b)*/ return(1);
   }
}

int main()
{
   int tableau[10] = { -14, -10, -3, 2, 7, 9, 11, 25, 45, 90};

   int a = 26;
   int *index;

   printf("adresse du tableau %p\n", tableau);
   index = (int *) bsearch(&a, tableau, 10, sizeof(int), (void *)(&compare));
   if (index == NULL)
   {
      printf("element non trouve\n");
   }
   else 
   {
   printf("element trouve = %d (%p), index %d \n", *index, index, index-tableau);
   }
   return(0);
}

test_enum.c

#include <stdio.h>

int main()
{
   typedef enum jour {lundi, mardi=10, mercredi, jeudi, vendredi, samedi, dimanche} Jour;
   Jour jour1, jour2;

   jour1 = lundi;

   jour2 = mercredi;

   printf("jour1 = %d\n", jour1);
   printf("jour2 = %d\n", jour2);
   printf("dimanche = %d\n", dimanche);
   return(0);

}

ex_liste.c

#include <stdio.h>
#include <stdlib.h>

typedef struct liste liste, *listePtr;

struct liste {
   int entier;
   listePtr suivant;
};

int listevide(listePtr l)
{
   return(l == NULL);
}

listePtr suivant(listePtr l)
{
   return(l->suivant);
}

listePtr delete(listePtr l)
{
   if (listevide(l))
   {
      return(l);
   }
   else
   {
      listePtr p = l;
      listePtr q;
      if (suivant(p) == NULL)
      {
         free(p);
         return(NULL);
      } 
      q = suivant(p);
      while (suivant(q) != NULL)
      {
         p = q;
         q = suivant(q);
      }
      free(q);
      p->suivant = NULL;
      return(l);
   }
}

listePtr insert(listePtr l, int n)
{
   listePtr element = NULL;

   element = (listePtr) malloc(sizeof(liste));
   if (element == NULL) exit(1);
   element->entier = n;
   element->suivant = NULL;
   if (listevide(l))
   {
      return(element);
   }
   else
   {
      listePtr elt_courant;
      elt_courant = l;
      while (suivant(elt_courant) != NULL)
      {
        elt_courant = elt_courant->suivant;
      }
      elt_courant->suivant = element;
   }
   return(l);
}

int main(int argc, char *argv[])
{
   int i;
   int n;

   listePtr l = NULL;
   listePtr m = NULL;

   for (i = 1; i < argc; i++)
   {
       n = atoi(argv[i]);
       l = insert(l, n);
   }

   i = 0;
   m = l;
   while (! listevide(m))
   {
     i = i+1;
     printf("Element %d = %d \n", i, m->entier);
     m = suivant(m);
   }
   printf("-------------------------\n");
   l = delete(l);
   i = 0;
   m = l;
   while (! listevide(m))
   {
     i = i+1;
     printf("Element %d = %d \n", i, m->entier);
     m = suivant(m);
   }
   return(0);
}

affiche.h

extern void affiche(int, int);
extern int add_entiers(int, int);

define.c

#include <stdio.h>

#define DIX       10
#define SOMME1   (12+8)
#define SOMME2    12+8

int main()
{
   int a;
   printf("dix = DIX = %d\n",DIX);
   a = SOMME1*5;
   printf("a = SOMME1*5 = %d\n", a);
   a = SOMME2*5;
   printf("a = SOMME2*5 = %d\n", a);
   return(0);
}

define2.c

#include <stdio.h>
#include <math.h>

#define CARRE(a)    ((a)*(a))
#define FABS(a)     ((a>0)?(a):(-a))
#define SCAL(x,y)   (((x)*(y))/sqrt(CARRE(x)*CARRE(y)))

int main()
{
   int n = 10;
   double x = -2.3;
   double y = 2.5;
   int i;

   for (i=0; i<n; i++)
      printf("Le carre de %d vaut %d\n", i, CARRE(i));
   printf("valeur absolue de %f = %f\n",x,FABS(x));
   printf("valeur absolue de %f = %f\n",-x,FABS(-x));
   printf("scal(%f,%f) = %f\n",x,y,SCAL(x,y));
   return(0);
}

affiche.c

#include <stdio.h>
#include "affiche.h"


int main()
{
   int a;
   int b;
   int c;

   a = 5;
   b = 7;
   printf("addresse de a: %p\n", &a);
   printf("addresse de b: %p\n", &b);
   printf("valeur de c: %d\n", c);
   printf("addresse de c: %p\n", &c);
   c = add_entiers(a, b);
#ifdef AFFICHE
   affiche(c,3.56);
#endif
#define AFFICHE
   a = add_entiers(c, a);
   return(0);
}

Correction des exercices

Listing 1: moyenne-lucie.c

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/* lecture: lecture d'un fichier par colonne
 * entree: pointeur sur un fichier
 *         nombre total de colonne par ligne
 *         la colonne a lire
 * sortie: la somme
 *         le nombre de ligne lues
 */
int lecture(FILE *ptr_fichier, int total, int colonne, double *somme,int *j)
{
    float valeur;
    int i=0; /* compteur de ligne */

        /* initialisation des valeurs */
        *somme = 0.;
        *j = 0;
        /* lecture des colonnes du fichier */
    while (fscanf(ptr_fichier,"%f",&valeur) != EOF)
    {
        i=i+1;
        if (i%total==colonne) 
        {
            *somme = *somme + (double) valeur;
            *j=*j+1;
        }
    }
    return(0);
}
int affiche(double *moy)
{
    printf("la moyenne de la colonne du milieu vaut %f\n",*moy);
    return(0);
}

FILE *ouverture(char nom_fichier[], char mode[])
{
        FILE *ptr_fichier;
    printf("ouverture fichier %s\n",nom_fichier);
    ptr_fichier = (FILE *) fopen(nom_fichier, mode);
    if (ptr_fichier == NULL)
    {
        printf("Erreur sur le fichier %s\n",nom_fichier);
        exit(1);
    }
        return (ptr_fichier);
}

int main()
{
    char nom_fichier[] = "liste_nb";
        int colonne = 2;
        int colonne_total = 3;

    double somme=0;
    double moy = 0.;
    int j=0;

        FILE *filePtr;

        filePtr = ouverture(nom_fichier, "r");
    lecture(filePtr, colonne_total, colonne, &somme, &j);
        fclose(filePtr);
    moy = somme/j;
    affiche(&moy);
    return(0);
}

Listing 2: moyenne-jennifer.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define GRANDE_TAILLE 1000000

double traitement(int colonne,char nom_fichier[])
{
  FILE *pointeur_fichier = NULL;
  double nombre = 0;
  double somme = 0;
  double moyenne = 0;
  char ligne[GRANDE_TAILLE];
  char *morceau;
  char *morceau2;
  int nombre_lignes = 0;
  int i = 0;

  /* on ouvre le fichier */
  pointeur_fichier = (FILE *) fopen(nom_fichier,"r");

  /* on verifie qu’il est bien ouvert*/
  if(pointeur_fichier == NULL)
  {
    printf("Erreur d’ouverture du fichier %s\n",nom_fichier);
    exit(1);
  }
  printf("fichier %s :\n",nom_fichier);

  /* Lit ligne par ligne jusqu'à la fin du document */
  while ((fgets(ligne,sizeof(ligne),pointeur_fichier)) != NULL)
  {
    morceau = ligne;
    for (i=0;i<colonne;i++)
    {
      if (morceau[0] == '\n')
      {  
        printf("Le nombre de colonnes est inferieur au nombre indique\n");
        exit(1);
      }
      nombre = strtod(morceau,&morceau2);
      morceau = morceau2;
    }
    nombre_lignes++;
    printf("nombre %d : %lf\n",nombre_lignes,nombre);
    somme = somme + nombre;
  }

  moyenne = somme / nombre_lignes;

  return(moyenne);
}


int main(int argc, char *argv[])
{
  int colonne = 0;
  double moyenne = 0;

  /* On vérifie le nombre d'arguments */
  if (argc != 3)
  {
    printf("Erreur ! \n");
    printf("%s: Nombre d'arguments incorrect\n\n", argv[0]);
    printf("Usage: %s numero_colonne nom_fichier\n", argv[0]);
    exit (1);
  }

  sscanf(argv[1],"%d",&colonne);

  moyenne = traitement(colonne,argv[2]);

  printf("moyenne = %lf\n",moyenne);

  return(0);
}

Listing 3: moyenne.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void moyenne(FILE *filePtr, int colonne)
{
   const int N = 1000;
   char ligne[N];
   char *token;
   int compteur = 0;

   double item = 0.;
   double moyenne = 0.;
   int n = 0;

   while (fgets(ligne, N, filePtr) != NULL)
   {
/* utilisation de strtok:
 * on regarde chaque "item" de la ligne separe par des espaces,
 * on compte jusqu'a la bonne colonne
 */
      token = strtok(ligne," \t\n");
      compteur = 0;
      while (token != NULL)
      {
         compteur += 1;
         if (compteur == colonne) break;
         token = strtok(NULL, " \t\n");
      }
/* sortie de boucle
 * deux choix:
 *  1) compteur == colonne, on peut faire la moyenne
 *  2) compteur != colonne, erreur (pas assez de colonne
 */
      if (compteur == colonne)
      {
         item = atof(token);
         moyenne = (item + moyenne*n)/(n+1);
         n += 1;
         printf("\r%d %f",n, moyenne);
      }
      else
      {
         printf("Erreur: nombre de colonne incorrects\n");
         printf("ligne: %s", ligne);
         printf("nombre de colonne recherche: %d\n", colonne);
         printf("nombre de colonne trouve: %d\n", compteur);
         exit(1);
      }
   }
   printf("\n");
}

int main(int argc, char *argv[])
{
   FILE *filePtr = NULL;
   int colonne;
   int error = 0;

   switch(argc)
   {
      case 2:
         /* recherche a partir de l'entree standard */
         colonne = atoi(argv[1]);
         moyenne(stdin, colonne);
         break;
      case 3:
         /* recherche a partir d'un fichier nomme */
         filePtr = fopen(argv[2], "r");
         if (filePtr == NULL)
         {
            printf("Erreur d'ouverture du fichier: %s\n", argv[2]);
            exit(1);
         }
         colonne = atoi(argv[1]);
         moyenne(filePtr, colonne);
         fclose(filePtr);
         break;
      default:
         printf("Erreur: Nombre d'arguments incorrect\n");
         printf("Usage: moyenne colonne [FICHIER]\n");
         printf(" - colonne : argument obligatoire, le numero de colonne a moyenner\n");
         printf(" - FICHIER : argument optionnel, le nom du fichier a traiter\n");
         exit(1);
   }

   return(error);
}

Listing 4: fgrep.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void recherche(FILE *filePtr, char *motif, char *nomfichier)
{
   const int N = 1000;

   char ligne[N];

   while (fgets(ligne, N, filePtr) != NULL)
   {
      if (strstr(ligne, motif) != NULL)
      {
         if (nomfichier != NULL)
            printf("%s:%s", nomfichier, ligne);
         else
            printf("%s", ligne);
      }
   }
}

int main(int argc, char *argv[])
{
   FILE *filePtr = NULL;
   int i;
   int error = 0;

   switch(argc)
   {
      case 1:
         printf("Erreur: Nombre d'arguments incorrect\n");
         printf("Usage: fgrep MOTIF [FICHIER]\n");
         exit(1);
      case 2:
        /*  printf("Recherche dans l'entree standard le motif: %s\n", argv[1]); */
         recherche(stdin, argv[1], NULL);
         break;
      case 3:
         filePtr = fopen(argv[2], "r");
         if (filePtr == NULL)
         {
            printf("Erreur d'ouverture du fichier: %s\n", argv[2]);
            exit(1);
         }
         /* printf("Recherche dans %s le motif: %s\n", argv[2], argv[1]); */
         recherche(filePtr, argv[1], NULL);
         fclose(filePtr);
         break;
      default:
         for (i = 2; i < argc; i++)
         {
            filePtr = fopen(argv[i], "r");
            if (filePtr == NULL)
            {
               printf("Erreur d'ouverture du fichier: %s\n", argv[i]);
               /* exit(1); */
               error = 1;
            }
            else
            {
               /* printf("Recherche dans %s le motif: %s\n", argv[i], argv[1]); */
               recherche(filePtr, argv[1], argv[i]);
               fclose(filePtr);
            }
         }
         break;
   }

   return(error);
}

Listing 5: makefile.lucie

# definition de quelques variables
CC=gcc -O -Wall -ansi

# utilisation de variables predefinies
# $@: la cible
# $^: l'ensemble des dependances
# $<: une dependance

# on indique que "all" est une cible virtuelle 
# (il n'y a pas de fichier a creer sous ce nom)
.PHONY: all

all: moyenne masse_molaire

moyenne: moyenne.c
    ${CC} -o $@ $<

masse_molaire: masse_molaire.o liste_elt.o
    ${CC} -o $@ $^
masse_molaire.o: masse_molaire.c liste_elt_vrai.h
    ${CC} -c $<
liste_elt.o: liste_elt.c liste_elt_vrai.h
    ${CC} -c $<

Listing 6: liste_elt_vrai.h

typedef struct liste liste, *listePtr;

struct liste {
   char symbol;
   double mass;
   listePtr suivant;
};

extern int listevide(listePtr);
extern listePtr suivant(listePtr);
extern listePtr delete(listePtr);
extern listePtr insert(listePtr, char, double);
extern void free_liste(listePtr);

Listing 7: masse_molaire.c

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include "liste_elt_vrai.h"

/*
 * fonction de lecture de l'entrée standard
 * entre dans une liste la molécule sous forme de chaine
 * C2H4 : C->C->H->H->H->H avec le nom de l'element et sa masse molaire
 */
listePtr
lecture (char s[1000])
{
  int i = 0, n = 0, k = 0;
  char symb = 'a';
  char stTemp[2];
  char stMass[5];
  int p;
  double m = 0.;
      FILE *fichier = NULL;
      char nom_fichier[] = "liste_atom";
      char temp[1000];
      int compteur = 0;


  listePtr l = NULL;


  printf ("Please enter the molecule :\n");
  fgets (s, 1000, stdin);   /*lit la ligne de l'entrée standard*/
  n = strlen (s);
/*
 * repartit la ligne de l'entrée standard entre lettres et chiffres
 */
  for (i = 0; i < n-1; i++)
    {
      if (isalpha (s[i]))
    {
      /*traitement des lettres*/
      symb = s[i];
      fichier = fopen (nom_fichier, "r");   /*ouverture du fichier qui contient les masses molaires*/
      if (fichier == NULL)  /*traitement de l'erreur d'ouverture du fichier*/
        {
          printf ("Erreur sur le fichier %s\n", nom_fichier);
          exit (1);
        }
          compteur = 0;
      while (fgets (temp, 1000, fichier) != NULL)   /*lecture du fichier jusque EOF*/
        {
          compteur++;
          if (strchr (temp, symb))  /*comparaison des chaines de caractère de elements en vue de prendre la masse molaire de l'element concerné pour l'introduire dans la liste*/
        {
          printf ("ligne %d : %s \n", compteur, temp);
                  strncpy(stMass,temp+2,4);
          m = atof (stMass);
                  /*
          for (j = 3; j < 6; j++)
            {
              sprintf (stMass, "%c", temp[j]);
              m = atof (stMass);
            }
                  */
        }
        }
          fclose(fichier);

      printf ("element  %d = %c  masse = %f \n", i, symb, m);
      l = insert (l, symb, m);  /*insere l'element (et sa masse molaire) dans la liste*/
    }
      /* traitement des chiffres*/
      else if (isdigit (s[i]))
    {

      sprintf (stTemp, "%c", s[i]); /*conversion du caractère en chaine de caractère*/
      p = atoi (stTemp);    /*conversion de la chaine en entier*/
      printf ("element %c should be counted %d times \n", symb, p);
      printf ("inserting %c %d more time\n", symb, (p - 1));
      for (k = 1; k < p; k++)   /*element a deja ete insere une fois, il doit etre insere encore p-1 fois*/
        {
          l = insert (l, symb, m);
        }
    }
      else
    {
      printf ("Erreur: caractere non reconnu: %c\n", s[i]);
      exit (1);
    }
    }
  if (listevide (l))
    printf ("liste vide");  /*teste si la liste est bien remplie*/
  printf ("\n");
  return (l);
}

int
main ()
{
  char s[1000];
  int i = 0;
  listePtr liste;
  listePtr tempo;

  liste = lecture (s);

  tempo = liste;
  while (!listevide (tempo))
    {
      i = i + 1;
      printf ("Element %d = %c \n", i, tempo->symbol);
      printf ("Element %d = %f \n", i, tempo->mass);
      tempo = suivant (tempo);
    }

   free_liste(liste);
  return (0);
}

Listing 8: liste_elt.c

#include <stdio.h>
#include <stdlib.h>

#include "liste_elt_vrai.h"
/*
typedef struct liste liste, *listePtr;

struct liste {
   char symbol;
   double mass;
   listePtr suivant;
};
*/

int listevide(listePtr l)
{
   return(l == NULL);
}

listePtr suivant(listePtr l)
{
   return(l->suivant);
}

listePtr delete(listePtr l)
{
   if (listevide(l))
   {
      return(l);
   }
   else
   {
      listePtr p = l;
      listePtr q;
      if (suivant(p) == NULL)
      {
         free(p);
         return(NULL);
      } 
      q = suivant(p);
      while (suivant(q) != NULL)
      {
         p = q;
         q = suivant(q);
      }
      free(q);
      p->suivant = NULL;
      return(l);
   }
}

void free_liste(listePtr l)
{
   listePtr tempo;

   while (! listevide(suivant(l)))
   {
      tempo = suivant(l);
      printf("libere element %c\n", l->symbol);
      free(l);
      l = tempo;
   }
   printf("libere element %c\n", l->symbol);
   free(l);
}

listePtr insert(listePtr l, char a, double m)
{
   listePtr element = NULL;

   element = (listePtr) malloc(sizeof(liste));
   if (element == NULL) exit(1);
   element->symbol = a;
   element->mass = m;
   element->suivant = NULL;
   if (listevide(l))
   {
      return(element);
   }
   else
   {
      listePtr elt_courant;
      elt_courant = l;
      while (suivant(elt_courant) != NULL)
      {
        elt_courant = elt_courant->suivant;
      }
      elt_courant->suivant = element;
   }
   return(l);
}

/*
int main(int argc, char *argv[])
{
   return(0);
}
*/