Chaînes de caractères | Exercices 1-5

Enoncé exercice 1

Ecrire un programme C qui lit une chaîne de caractères et vérifie si elle est palindrome ou non. On rappelle qu’une chaîne de caractères est dite palindrome, si elle se lit de la même manière dans les deux sens. Exemple: non, touot et 1234321 sont toutes des chaînes de caractères palindromes.

Correction exercice 1

Cet exercice est un exercice classique pour les chaines de caractères. On va y tester si une chaîne de caractères donnée est palindrome ou non. C’est à dire est ce qu’elle peut se lire dans les deux sens de la même manière.

Dans l’algorithme adopté pour cet exercice on va comparer le premier caractère de la chaîne avec le dernier, le deuxième avec l’avant dernier et ainsi de suite jusqu’à arriver au milieu de la chaine. Et chaque deux caractères comparés doivent être égaux pour que la chaîne de caractères soit palindrome.

Avant de commencer le programme il ne faut pas oublier d’ajouter la bibliothèque standard string.h aux directives du préprocesseur (ligne 3).

On commencera le programme en déclarant de la chaine s sur laquelle on va effectuer le test (ligne 6). On va la lire ensuite avec la fonction scanf (ligne 9).

On va supposer maintenant que s est palindrome en mettant la variable entière ok à 1 (ligne 10). Après, et pour faire le test on aura besoin d’un compteur i qui commencera par le premier caractère de la chaine (i=0) et un autre compteur j qui va quant à lui commencer par le dernier caractère. L’indice du dernier caractère peut être déduit à partir de la taille de la chaîne s qui est donnée par la fonction strlen() qui prend en argument une chaîne de caractères est calcul sa taille. Ainsi, la valeur de départ pour j sera strlen(s)-1. Cette initialisation sera effectuée dans le premier bloc de la boucle for (ligne 11). La décrémentation de j est effectuée en parallèle à l’incrémentation de i.

A l’intérieur de la boucle for on compare s[i] avec son symétrique s[j] (ligne 13). Et s’ils sont différents s ne sera pas palindrome. On le signale en mettant la variable ok à 0 (ligne 15). Et dans ce cas on sort de la boucle à l’aide de l’instruction break (ligne 16).

A l’extérieur de la boucle for on fait un test sur la valeur de la variable ok, si elle est égale à 1, on dira que la chaîne de caractères est palindrome, sinon on affiche qu’elle n’est pas palindrome.

Solution exercice 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char s[100];
    int i,j,ok;
    printf("Donnez une chaine de caracteres:\n");
    scanf("%s",s);
    ok=1;
    for(i=0,j=strlen(s)-1;i<j;i++,j--)
    {
       if(s[i]!=s[j])
       {
         ok=0;
         break;
       }
    }
    if(ok==1) printf("%s est palindrome.\n",s);
    else printf("%s n'est pas palindrome.\n",s);
    system("pause");
    return 0;
}
Enoncé exercice 2

Ecrire un programme C qui lit deux chaînes de caractères et les affiche dans l’ordre alphabétique, en utilisant les deux méthodes suivantes:

• En utilisant la fonction strcmp.
• Sans utiliser la fonction strcmp.

Par exemple, si on donne en entrée les deux chaînes suivantes: acb et abcd, le programme doit afficher la chaîne abcd puis acb.

Correction exercice 2

Dans cet exercice on doit comparer deux chaînes de caractères, et les afficher dans l’ordre alphabétique ou plus généralement selon l’ordre déduit du code ASCII. Car les deux chaînes de caractères peuvent contenir des caractères non alphabétiques comme les espaces ou les chiffres.

Pour ce faire, on va déclarer deux chaînes de caractères: s1 et s2 qu’on va lire à l’aide de la fonction gets. Pour la première méthode on va utiliser la fonction strcmp, définie dans la bibliothèque standard string.h, et qui prend en paramètres les deux chaînes de caractères à comparer. Dans ce cas il s’agit de s1 et s2. Donc, strcmp sera utilisée de la façon suivante: strcmp(s1,s2), cette quantité est un entier qui peut être selon l’ordre relatif des deux chaînes:

• Négatif: si s1 vient avant s2 dans l’ordre alphabétique.

• Positif: si s2 vient avant s1 dans l’ordre alphabétique.

• Nul: s’il s’agit de la même chaîne de caractères.

Donc il suffit de faire un test sur le signe de strcmp(s1,s2) pour déduire l’ordre relatif des deux chaînes. On peut remarquer que l’ordre des paramètres s1 et s2 est pris en considération, et que strcmp(s1,s2) et strcmp(s2,s1) sont de signes différents.

Pour la deuxième méthode on va essayer de comparer les deux chaînes en utilisant des outils de base, à savoir les boucles et les conditions. Le principe est très simple: on va parcourir les deux chaînes de caractères et on comparera deux à deux les caractères qui ont le même indice, et ceci on commençant par le premier caractère. Tant qu’on ne trouve que des caractères identiques on ne peut pas conclure sur l’ordre et on passe à la position qui suit. Cette tâche est réalisée par l’instruction if(s1[i]==s2[i]) continue; (ligne 25) qui veut dire que si on a s1[i]==s2[i], on passera alors de ce point vers l’itération suivante de la boucle sans exécuter le restant des instructions de la boucle for. Dans le cas où les deux caractères sont différents, la chaîne avec le plus petit caractère sera première dans l’ordre alphabétique, on tranche sur ce sujet à l’aide de la structure de contrôle if else (lignes 26-27), et on sort de la boucle (ligne 28).

Il est évident qu’on doit s’arrêter au maximum lorsque l’une des deux chaînes se termine, ceci est assuré par la condition de la boule for: i<strlen(s1) && i<strlen(s2) (ligne 23).

Jusqu’au point où on est, la boucle for donnera un ordre si elle trouve deux caractères différents avant la fin d’une des deux chaînes, donc si on donne en entrées les deux chaînes: abc et abcd, la boucle à elle seule ne peut pas décider. La solution à ce problème est très simple à mettre en place, elle consiste à faire un test sur la valeur du compteur i, juste après la fin de la boucle, et voir si elle est égale à la taille de l’une des deux chaînes et s’il en est le cas, ça voudrait dire que la chaîne dont la taille est égale à i, est la plus courte, donc forcément elle viendra première dans ordre alphabétique.

Solution exercice 2
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
        char s1[100],s2[100];
        int i;
        printf("Donnez deux chaines de caracteres:\n");
        gets(s1);
        gets(s2);
        printf("En utilisant la fonction strcmp:\n");
        if( strcmp(s1,s2)<0 )
        {
            puts(s1);
            puts(s2);
        }
        else
        {
            puts(s2);
            puts(s1);
        }
        printf("Sans utilisation de la fonction strcmp:\n");
        for(i=0;i<strlen(s1) && i<strlen(s2); i++)
        {
            if(s1[i]==s2[i]) continue;
            if(s1[i]<s2[i]) { puts(s1); puts(s2);}
            else { puts(s2); puts(s1);}
            break;
        }
        if(i==strlen(s1) )
        {
            puts(s1); puts(s2);
        }
        else if(i==strlen(s2) )
        {
            puts(s2); puts(s1);
        }
        system("pause");
        return 0;
}
Enoncé exercice 3

Ecrire un programme C qui lit deux chaînes de caractères et permute leurs contenus en utilisant les deux méthodes suivantes:

• Avec la fonction strcpy;

• Sans la fonction strcpy.

Correction exercice 3

Dans cet exercice on va voir deux méthodes différentes pour échanger le contenu de deux chaînes de caractères. Sachant que l’opération de permutation se base sur une série de trois affectations, et que l’opérateur = n’est pas valable pour les chaînes de caractères, on utilisera donc la fonction strcpy définie dans la bibliothèque string.h et qui réalise l’affectation en recevant les deux chaînes concernées.

Donc, pour mettre le contenu d’une chaîne s1 dans s2 il suffit d’utiliser l’instruction strcpy(s2,s1). Bien évidement s1 ne va pas changer et s2 sera la même que s1.

La permutation est effectuée en utilisant cette fonction pour l’affectation, et en se servant d’une chaîne de caractères intermédiaire tmp en plus de l’algorithme de permutation classique (lignes 12-14):

tmp reçoit le contenu de s1;

s1 reçoit le contenu de s2;

s2 reçoit le contenu de tmp.

Après avoir effectuer ces trois instructions à l’aide de strcpy, le contenu des deux chaînes devra être permuté. Pour pouvoir vérifier ceci on les affiche avec la fonction puts (lignes 15-16).

Pour la deuxième méthode on parcourt les deux chaînes de caractères et à chaque fois on permute les deux caractères qu’ont la même position en se servant de l’algorithme de permutation cité précédemment (lignes 20-22).

Les deux chaînes à permuter n’auront pas forcément la même longueur, c’est pour ça que la boucle de parcourt doit arriver jusqu’au dernier caractère de la chaîne la plus longue, il doit même le dépasser par une case pour pouvoir accéder au caractère délimitant la chaîne \0 qui se trouve juste après le dernier caractère de la chaîne. Ceci est concrétisé avec la condition de la boucle for i<=strlen(s1) || i<=strlen(s2) (ligne 18).

Après l’affichage des deux chaînes de caractère s1 et s2 (lignes 24-25) on remarquera qu’elles ont reprise leurs valeurs initiales, puisqu’elles ont été déjà inversées dans la première partie du programme.

Solution exercice 3
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char s1[100],s2[100],tmp[100],c;
    int i;
    printf("Donnez deux chaines de caracteres:\n");
    gets(s1);
    gets(s2);
    printf("En utilisant la fonction strcpy:\n");
    strcpy(tmp,s1);
    strcpy(s1,s2);
    strcpy(s2,tmp);
    puts(s1);
    puts(s2);
    printf("Sans utilisation de la fonction strcpy:\n");
    for(i=0;i<=strlen(s1) || i<=strlen(s2); i++)
    {
        c=s1[i];
        s1[i]=s2[i];
        s2[i]=c;
    }
    puts(s1);
    puts(s2);
    system("pause");
    return 0;
}
Enoncé exercice 4

Ecrire un programme C qui lit une chaîne de caractères, et transforme chaque caractère majuscule en minuscule et vice versa.

Correction exercice 4

La première chose évidente à faire sera de parcourir la chaîne de caractères avec une boucle for. Et pour chaque caractère on vérifie s’il est alphabétique et en même temps sa nature. Il sera donc une:

– Majuscule: si la condition suivante est vérifiée: ‘A'<=s[i] && s[i]<=’Z’ ;

– Minuscule: si la condition suivante est vérifiée: ‘a'<=s[i] && s[i]<=’z’.

S’il ne vérifie aucune des deux conditions précédentes ce caractère ne doit pas être altéré.

Pour transformer un caractère majuscule en minuscule, il suffit d’en soustraire le caractère A et lui ajouter a comme suit : s[i]=s[i]-‘A’+’a’. Et d’une manière similaire on va utiliser s[i]=s[i]-‘a’+’A’ pour transformer une minuscule en majuscule (lignes 11-18).

On remarque qu’en présence d’une minuscule le programme va exécuter le bloc d’instructions de la première condition (ligne 11) et transformer le caractère en une majuscule. Et juste après, il puisqu’il s’agit maintenant d’une majuscule le deuxième bloc va la retransformer vers une minuscule. Pour éviter ce problème, on va utiliser l’instruction continue pour passer au caractère suivant sans avoir à exécuter le restant des instructions de la boucle for (ligne 14). Il faudra essayer d’exécuter le programme en enlevant cette instruction pour voir son effet.

Solution exercice 4
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char s[100];
    int i;
    gets(s);
    for(i=0;i<strlen(s);i++)
    {
        if( 'a'<=s[i] && s[i]<='z' )
        {
            s[i]=s[i]-'a'+'A';
            continue;
        }
        if( 'A'<=s[i] && s[i]<='Z' )
            s[i]=s[i]-'A'+'a';   
    }
    puts(s);
    system("pause");
    return 0;
}
Enoncé exercice 5

Ecrire un programme C qui lit deux chaînes de caractères et vérifie si la deuxième est une sous chaîne de la première ou non.
Exemple: tout est une sous chaîne de surtout.

Correction exercice 5

Dans cet exercice on va lire deux chaînes de caractères s et ch et essayer de vérifier si ch constitue une sous chaîne de s. Pour ce faire, on va parcourir la chaîne s jusqu’à ce qu’on trouver un caractère de s qui est le même que le premier caractère de la chaîne ch qui est ch[0]. Une fois trouvé dans une position i, on souhaitera que les m-1 caractères (m étant la taille de ch) qui suivent seront les mêmes que le restant des caractères de ch, c-à-d: s[i] == ch[0], s[i+1] == ch[1] et ainsi de suite jusqu’à s[i+(m-1)] == ch[m-1].

Pour faire cette vérification, on va utiliser une boucle for de compteur j (ligne 17) pour parcourir ch et comparer à chaque itération ch[j] avec s[i+j] et si on trouve que pour un certain j que ces deux caractères sont différents, ça veut dire que la sous chaîne s[i], s[i+1], …, s[i+m-1] n’est pas la même que ch et on sort cette boucle de compteur j en utilisant l’instruction break (ligne 18). Et on continue la recherche d’un autre caractère de s qui est égal à ch[0]. Dans le cas où tous ces caractères sont identiques la boucle continuera jusqu’à sa fin (j==m). Dans ce cas on va signaler que ch est une sous chaîne de s en mettant la variable ok à 1 (ligne 19). ok doit être initialisée à 0 (ligne 12).

Après ce qu’on sort de la boucle de compteur i, on fait un test sur la valeur de la variable ok, et on affiche le message correspondant.
Il reste à signaler que la boucle for (ligne 13) s’arrête lorsque i==n-m+1 qui est n-(m-1) puisque à partir de cette position le nombre de caractère qu’on a est inférieur à la taille de ch.

Solution exercice 5
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char s[100],ch[100];
    int i,j,ok,n,m;
    gets(s);
    gets(ch);
    n=strlen(s);
    m=strlen(ch);
    ok=0;
    for(i=0;i<n-m+1;i++)
    {
       if(s[i]==ch[0])
       {
         for(j=0;j<m;j++)
           if(s[i+j]!=ch[j]) break;
         if(j==m) ok=1;
       }
       if(ok==1) break;
    }
    if(ok==1) printf("'%s' est une sous chaine de '%s'.\n",ch,s);
    else printf("'%s' n'est pas une sous chaine de '%s'.\n",ch,s);
    system("pause");
    return 0;
}