1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
| #include <stdio.h>
#include <stdlib.h>
/* -tc- inutile et pas portable
#include <conio.h>
*/
#include <string.h>
/*******************************les structures*********************************/
struct prenom
{
char p[25]; /* prenom */
struct prenom *suiv;
};
/* -tc- Masquer un pointeur derriere un alias cette maniere, c'est pas terrible.
Ou alors, il faudrait que le nom de l'alias reflete le fait qu'il represente
un pointeur p.ex. en prefixant l'identificateur de l'alias par p_
*/
typedef struct prenom * p_listeprens;
/****************************fclean()******************************************/
int fclean (char *buffer, FILE * fp)
{
int err = 0;
if (buffer != NULL && fp != NULL)
{
char *pc = strchr (buffer, '\n');
if (pc != NULL)
{
/* On remplace '\n' par le caractere nul '\0' */
*pc = 0;
}
else
{
/* La saisie a ete tronquee, on purge le flux entrant */
int c;
while ((c = fgetc(fp)) != '\n' && c != EOF)
{
}
err = 1;
}
}
return err;
}
/*************************inserordre*******************************************/
int inserordre(p_listeprens *adlp, char *pren)
{
struct prenom *nouv = NULL;
struct prenom *bal = NULL;
struct prenom *prec = NULL;
nouv = malloc(sizeof *nouv);
if (nouv != NULL)
{
/* -tc- creation d'une structure statique dont tous les champs sont
initialises a zero */
static struct prenom const tmp;
/* -tc- Initialisation de nouv */
*nouv = tmp;
/* -tc- C'est une bonne idee de securiser la copie */
strncat(nouv->p, pren, sizeof nouv->p - 1);
bal = *adlp;
while (bal != NULL && strcmp(bal->p, pren) < 0)
{
prec = bal;
bal = bal->suiv;
}
if (bal == *adlp)
{
/* -tc- la liste est vide */
*adlp = nouv;
nouv->suiv = bal;
}
else
{
prec->suiv = nouv;
nouv->suiv = bal;
}
/* -tc- Outre le fait que je n'aime en general pas utiliser des return
sauvages, je trouve toujours etrange, en C, de renvoyer 1 lorsque tout
s'est bien passe. */
return 1;
}
else
{
return 0;
}
}
/****************************lireordre()***************************************/
/* -tc- Par soucis de symetrie entre declaration et definition de fonction, je
conseille de toujours dedfinir une fonction a l'aide d'un prototype. En
particulier, une liste vide d'arguments devrait etre specifiee par void. */
p_listeprens lireordre(void)
{
p_listeprens lst = NULL;
char pren[25] = "";
int end = 0;
while (end == 0 && fgets(pren, sizeof pren, stdin) != NULL)
{
fclean(pren, stdin);
if (strcmp(pren, ".") != 0 && inserordre(&lst, pren) == 1)
{
}
else
{
end =1;
}
}
return lst;
}
/***********************************ecrire************************************/
void ecrire(p_listeprens lp)
{
while (lp != NULL)
{
printf("%s ", lp->p);
lp = lp->suiv;
}
}
/***************************main**********************************************/
/* -tc- main() renvoit un entier de type int, toujours! */
int main(void)
{
p_listeprens lp;
printf("Entrer une suite de prenoms (un par ligne) et terminer par un \'.\':\n");
lp = lireordre();
printf("dans l'ordre:\n");
ecrire(lp);
/* -tc- inutile et pas portable
getch();
*/
/* -tc- main() doit retourner 0, EXIT_SUCCESS ou EXIT_FAILURE */
return 0;
} |
Partager