Tous les programmes mentionnés dans ce solutionnaire sont disponibles ici en format ZIP.

11–1

Le prototype de cette fonction est: int Reponse(const char * s);

A) Cette version nécessite la programmation de plusieurs fonctions étant donné que l'énoncé de la question bloquait l'utilisation de la librairie string.h. voir REP11_1A.C
B) La version la plus simple. voir REP11_1B.C
C) 'utilisation de la fonction "strstr" rend difficile le fait de ne pas prendre en compte les variantes qui se trouvent coincées à l'intérieur d'un mot. Par exemple, dans le mot "proposition", il y a un "si" qui ne doit pas être compté. Il faut donc vérifier si le caractère qui suit ce "si" est bien un séparateur, ce qui complique le traitement. voir REP11_1C.C
D) La plus stable et la plus sécuritaire est sans aucun doute la version B.
11–2

Trois programmes effectuant la tâche demandée au No 2 présentent les trois versions de la fonction Reponse en action. Ils sont disponibles sous les noms: REP11_1A.C, REP11_1B.C et REP11_1C.C dans le fichier ZIP des programmes associés à ce solutionnaire.

11–3
char * maVersionDe_strupr(char * s) {
   int i;
   for (i = 0; i < strlen(s); i++)
      s[i] = toupper(s[i]);
   return s;
}

voir REP11_3.C
11–4

Cette fonction copie les 'n' premiers caractères de s2 dans s1 mais si jamais 'n' est plus grand que la longueur de s2, la fonction copie tous les caractères de s2 dans s1. Le comportement de cette fonction est semblable à celle de la librairie string.h en ce sens que si s1 est trop courte pour supporter les caractères copiés, il y a débordement.

Cependant, la paramétrisation de cette fonction ne fait pas apparaître le "const" au bon endroit. Le 'const' devrait être sur s2 et non sur s1 comme ceci:

char * mystere(char * s1, const char * s2, int n);

11–5 A)
int palindrome(const char * s){
  int i, k;
  i = 0; k = strlen(s) - 1;
  while (i < strlen(s)/2) {
     if (toupper(s[i]) != toupper(s[k])) return 0;
     i++;
     k--;
  }
  return 1;
}

on pourrait aussi, en utilisant la fonction strrev (qui renverse les caractères d'une chaîne) de la librairie string.h, écrire cette fonction de manière suivante:

int palindrome(const char * s){
  char * copie;
  int r;
  copie = (char *)malloc(strlen(s)+1);
  strcpy(copie, s); // on fait une copie de la chaîne originale
  strrev(copie);    // on renverse les caractères de la copie
  r = strcmpi(copie, s); // on compare les deux chaînes ainsi obtenues
  free(copie);
  if (r == 0) return 1;
  return 0;
}
B)

Dans cette version, comme 'ispunct' n'inclut pas les espaces, j'ai plutôt utilisé ici 'isalnum'.

int palindrome(const char * s){
  int i, k;
  i = 0; k = strlen(s) - 1;
  while (i < strlen(s) && k >= 0) {
     if (!isalnum(s[i])) { i++; continue; }
     if (!isalnum(s[k])) { k--; continue; }
     if (toupper(s[i]) != toupper(s[k])) return 0;
     i++;
     k--;
  }
  if (i == strlen(s) && k == -1) // on a terminé
     return 1;
  return 0;
}

voir REP11_5.C

11–6
char * remplaceCar(char * s, int c1, int c2) {
   int i;
   for (i = 0; i < strlen(s); i++)
      if (s[i] == c1) s[i] = c2;
   return s;
}
11–7

Voici une version qui utilise 'strcpy':

char * enleveCarVersion1(char * s, int c1) {
   int i;
   for (i = 0; i < strlen(s); i++) {
      if (s[i] == c1)
          strcpy(s + i, s + i + 1);
   }
   return s;
}

et une autre qui décale "manuellement" les caractères.

char * enleveCarVersion2(char * s, int c1) {
   int i, k;
   for (i = 0; i < strlen(s); i++) {
      if (s[i] == c1) {
          for (k = i; k < strlen(s)-1; k++)
             s[k] = s[k+1];
          s[k] = '\0';
      }
   }
   return s;
}

voir REP11_7.C

11–8
char * enleveStr(char * s1, const char * s2){
   char * p;
   p = strstr(s1, s2);
   while (p) {
      strcpy(p, p + strlen(s2));
      p = strstr(s1, s2);
   }
   return s1;
}

voir REP11_8.C

11–9
// s1 peut allonger ou raccourcir...
char * remplaceStr(char * s1, const char * s2, const char * s3){
   char resultat[255]; // limite sur la longueur du resultat final
   char * p;
   char * r;
   char * debut;
   debut = s1;
   
   resultat[0] = '\0';
   r = resultat;
   p = strstr(s1, s2);
   while (p) {
      strncpy(r, debut, p - debut);
      r = r + (p - debut);
      strcpy(r, s3);
      r = r + strlen(s3);
      debut = p + strlen(s2);
      p = strstr(debut, s2);
   }
   strcpy(r, debut);
   strcpy(s1, resultat);
   return s1;
}

voir REP11_9.C

11–10

J'ai utilisé le caractère * ET ^ pour représenter le \0. La barre verticale représente les valeurs successives de "p".

Contenu original de la variable 'ligne':

          1         2         3         4         5 
012345678901234567890123456789012345678901234567890123456789 VOICI, DANS LEUR SPLENDEUR(!), LES 1,800 CRAPULES!?*********
A)
Contenu en final de 'ligne':


|      |    |    |             |   | |   |
VOICI* DANS*LEUR*SPLENDEUR*!), LES*1*800*CRAPULES*?*********
     ^     ^    ^         ^       ^ ^   ^        ^


Et le bout de code affiche:
VOICI
DANS
LEUR
SPLENDEUR
LES
1
800
CRAPULES
B)
Contenu en final de 'ligne':



|      |    |    |             |         |
VOICI* DANS*LEUR*SPLENDEUR*!), LES*1,800 CRAPULES*?*********
     ^     ^    ^         ^       ^              ^
     
Et le bout de code affiche:
VOICI
DANS
LEUR
SPLENDEUR
LES
CRAPULES
C)
Contenu en final de 'ligne':



|      |    |     |            |   |       |  |
VO*CI, DAN* LE*R SPLENDE*R(!), LE* 1*800*CRAP*LE*!?*********
  ^       ^   ^         ^        ^  ^   ^    ^  ^
  
Et le bout de code affiche:
VO
DAN
LE
PLENDE
LE
1
800
AP
LE
11–11

Le résultat de l'affichage sera: SOURIS ... écrit 10 fois. L'assignation pose problème. Il faut plutôt écrire:

      strcpy(liste[i], mot); 

plutôt que:

      liste[i] = mot;
11–12

Oui car le pointeur 'ligne' désigne un emplacement qui ne nous appartient pas.

11–13

Oui car la variable 'ligne' reçoit l'adresse d'une variable qui est LOCALE à la fonction. Dès que la fonction termine son exécution, cette variable n'existe plus rendant l'utilisation subséquente du pointeur sur cette variable instable.

11–14

Deux problèmes: l'ajout de la ligne dans le tableau et la comparaison.

La ligne d'ajout:         liste[N++] = lig;
doit être réécrite ainsi: strcpy(liste[N++], lig); 
La ligne de comparaison:   if (liste[i] == lig) { 
doit être réécrite:        if (strcmpi(liste[i], lig) == 0) {
Modifié le: lundi, 16 juin 2014, 15:44