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

enum {MAXCAR = 11};

char * AlloueEtConcat(char *, char *);

void main()
{
      char prenom[MAXCAR], nom[MAXCAR];
      char * prenom_nom;

      printf("Donnez le prénom (au plus %d caractères) : ",MAXCAR - 1);
      fgets(prenom, MAXCAR, stdin);
      if (prenom[strlen(prenom)-1] == '\n') prenom[strlen(prenom) - 1] = '\0';
      fseek(stdin, 0, SEEK_END);
      printf("Donnez le nom (au plus %d caractères) : ",MAXCAR - 1);
      fgets(nom,MAXCAR,stdin);
      if (nom[strlen(nom) - 1] == '\n') nom[strlen(nom) - 1] = '\0';
      prenom_nom = AlloueEtConcat(prenom, nom);
      puts(prenom_nom);
      free(prenom_nom);
}

char * AlloueEtConcat(char * s1, char * s2)
{
      int longueur;
      char * s3;

      longueur=strlen(s1) + strlen(s2) + 2;
      s3=(char *) malloc(longueur*sizeof(char));
      if (s3==NULL)
      {
            puts("mémoire insuffisante");
            exit(1); }
      else
      {
            strcpy(s3, s1);
            strcat(s3, " ");
            strcat(s3, s2);
      }
      return s3;
}
include
Notre programme utilise les fonctions malloc et free qui se trouvent déclarées dans le fichiers
stdlib.h qu'il faut en conséquence inclure ici.

fgets(prenom,MAXCAR,stdin);
La fonction
fgets est déclarée dans stdio.h et est utile surtout lorsque l'on travaile avec des fichiers. Nous verrons les fichiers lors de l'exemple 7. Néanmoins, cette fonction a été choisie ici car elle permet de limiter le nombre de caractères lus de façon à ne pas risquer de déborder du tableau prenom.
Le fichier indiqué est ici stdin qui est le fichier standard d'entrée (en l'absence d'instruction changeant ce fichier, il s'agit du clavier).

char * AlloueEtConcat(char *, char *);
En C il n'existe pas de procédures mais seulement des fonctions. Jusqu'à présent nous n'avons rencontré dans nos exemples que des fonctions utilisées comme des procédures : nous en attendions qu'elles modifient les valeurs des variables globales du programme ou les valeurs de leurs propres paramètres.
Cependant, bien entendu, une fonction peut rendre un résultat. Ce résultat doit avoir comme type un type nommé.
Le
prototype de la fonction comporte successivement le type du résultat, puis l'identificateur de la fonction (son nom), et enfin, entre parenthèses, le types des paramètres.
Ici, la fonction AlloueEtConcat rend une valeur de type adresse de "char".

MAXCAR-1
Le tableau prénom dans lequel nous voulons stocker la chaîne de caractères indiquée par l'utilisateur étant de taille MAXCAR, l'utilisateur doit indiquer un prénom de longueur au plus MAXCAR-1, de façon à ce qu'il reste la place nécessaire au caractère \0 (caractère de valeur nulle) qui doit terminer toute chaîne de caractères.

char * prenom_nom;
prenom_nom est une variable de type adresse d'un caractère.
Dans notre programme, cette variable donnera l'adresse du premier élément du ableau de caractères qui contiendra la concaténation du prénom et du nom.
ATTENTION. Cette variable, au moment de sa définition, n'est pas initialisée. Tenter de lire ou d'écrire en *prenom-nom n'aurait aucun sens en début de programme.

strlen
La fonction
strlen est déclaré dans string.h.
Si l'utilisateur fournit un prénom ayant au plus MAXCAR-2 caractères, alors la fonction fgets met dans prenom le prénom de l'utilisateur, suivi de '\n' puis de '\0'. L'instruction dans laquelle figure la fonction strlen que nous commentons ici sert à éliminer, le cas échéant, le caractère de fin de ligne '\n'.

fseek(stdin, 0, SEEK_END);
La fonction fseek est déclarée dans stdio.h. C'est une fonction de positionnement dans un fichier. Utilisée comme elle l'est ici, elle signifie : se positionner dans le fichier stdin 0 caractère après le dernier caractère.
Autrement dit, cette fonction nous sert à nous positionner à la fin des caractères envoyés jusqu'à présent par le clavier.
Cette instruction est utile pour le cas où l'utilisateur aurait envoyé un prénom plus long que ce qu'a pu prendre fgets ; si on ne se positionnait pas ainsi en fin de fichier, la fin du prénom serait alors retenue comme nom.

(char *)
Vous avez ici l'exemple d'une
conversion de type ; cette conversion s'applique ici à la valeur retournée par la fonction malloc, qui est une adresse d'un "void", c'est-à-dire une adresse d'un type non défini. Pour qu'il y ait compatibilité avec le type de s3, il est nécessaire de convertir le type de cette valeur en le type char *, c'est-à-dire adresse de caractère (qui est le type de s3).

exit(1);
La fonction
exit est utilisée ici pour sortir du programme lorsque l'allocation mémoire a échouée.

return s3;
Cette instruction fait sortir de la fonction AlloueEtConcat et retourne à la fonction appelante la valeur s3. Le programme poursuit donc avec le main en mettant dans la variable prenom_nom la valeur de s3.


Irene Charon
Last modified: Mon Sep 13 12:24:33 MET DST 1999