Allocation et de comparaison des chaines de caractères [Résolu/Fermé]

Signaler
Messages postés
8
Date d'inscription
jeudi 31 janvier 2013
Statut
Membre
Dernière intervention
20 mars 2013
-
Messages postés
8
Date d'inscription
jeudi 31 janvier 2013
Statut
Membre
Dernière intervention
20 mars 2013
-
Bonjour tout le monde,
J'ai quelques problèmes avec les chaines de caractères, je vaudrais par exemple concevoir une petite interface qui pilote une machine, j'ai 3 choix:
- MS1=> Machine tourne en sens 1,
- MS2=> Machine tourne en sens 2,
- ARRET=> la machine s'arrête,

j'ai fait quelques tentatives, voici le code:
#include <stdio.h>
int main()
{
    char *strp;
    strp=(char*)malloc(5*sizeof(char));// Allocation mêmoire
    printf("Entrer votre choix\n");
    strp=gets(strp);
    //scanf("%s",strp);
    //strp="MS1";
    if (strcmp(toupper(strp),"MS1")==0) printf("Machine en Marche sens 1 \n");
    else if (strcmp(toupper(strp),"MS2")==0) printf("Machine en Marche sens 2\n");
    else if (strcmp(toupper(strp),"ARRET")==0) printf("Machine en Arret\n");
    else printf("Mauvais choix\n");
   free(strp); // Libération de la mêmoire
getchar();getchar();;
return 0;
}

Questions:
1- c'est possible de faire l'allocation mémoire après la réception de ma chaine? c-a-d une allocation dynamique en fonction de la chaine saisie, par exemple:
	char *strp;
    	printf("Entrer votre choix\n");
    	strp=gets(strp);
	strp=(char*)malloc(strlen(strp)*sizeof(char));// Allocation mêmoire
	// Résultat=> le compilo se plante !!
	


2- la fonction toupper n'agit pas sur une chaine de caractère?? notant que avec toupper(c) ça marche bien.

Merci.

2 réponses


Un code comme ça devrait faire l'affaire :

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

#define SIZE 10

int main() {
  char strp[SIZE] = {0};
  printf("Entrer votre choix : ");
  scanf("%s", strp);
  if (strcasecmp(strp,"MS1") == 0)
    printf("Machine en Marche sens 1 \n");
  else if (strcasecmp(strp,"MS2") == 0)
    printf("Machine en Marche sens 2\n");
  else if (strcasecmp(strp,"ARRET") == 0)
    printf("Machine en Arret\n");
  else
    printf("Mauvais choix\n");
  return 0;
}


Q1) Pas sûr que ce soit faisable. Le plus simple et de définir une taille (SIZE) max (ici : 10).
Q2) Pas besoin de convertir la chaine en caractères majusucle. Le plus simple est d'utiliser strcasecmp, qui a la même action que strcmp mais en ignorant la différence entre minuscule et majuscule.
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 60554 internautes nous ont dit merci ce mois-ci

Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 686
Allouer une taille max est bien, mais si tu utilises une fonction sans contrôle derrière, ça sert à rien ^^.
Et strcasecmp() n'est pas une fonction ISO C89/90...
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 686
Bonjour,

1/
Le plus simple est effectivement de réaliser une taille maximum genre 255 et d'utiliser fgets(). Il ne faut pas utiliser gets(), c'est obsolète et dangereux.
Donc cela donnerait :
#define MAX 255
char ch[MAX];

fgets(ch,sizeof ch, stdin);

Si tu souhaites vraiment, une chaine de la bonne taille, tu peux ensuite réutiliser :
char *strp=malloc(strlen(ch)+1);
et : strcpy(strp, ch);

2/Oui toupper() c'est pour un caractère. Il te faut donc faire une boucle pour agir sur chacun des caractères de la chaîne.
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 60554 internautes nous ont dit merci ce mois-ci

Messages postés
8
Date d'inscription
jeudi 31 janvier 2013
Statut
Membre
Dernière intervention
20 mars 2013

Re,
Merci pour vos réponses, J'ai essayé d'appliquer vos conseils et voici le code:
#include <string.h> 
#include <stdio.h> 
#define MAX 255 
int main() 
{ 
    char ch[MAX]; 
    printf("Entrer votre choix\n"); 
    fgets(ch,sizeof (ch), stdin); 
    char *strp=malloc(strlen(ch)+1);  
    strcpy(strp,ch);  

    if (strcmp(strp,"MS1")==0) printf("Machine en Marche sens 1 \n"); 
    else if (strcmp(strp,"MS2")==0) printf("Machine en Marche sens 2\n"); 
    else if (strcmp(strp,"ARRET")==0) printf("Machine en Arret\n"); 
    else printf("Mauvais choix\n"); 
   free(strp); // Libération de la mêmoire 
getchar();getchar();; 
return 0; 
} 


L'allocation dynamique, ainsi que les fonctions fgets et strcpy marchent T. Bien, mais j'ai encore un petit problème!!
Pour un choix "MS1" par exemple, la comparaison strcmp(strp,"MS1") ou même strcmp(strp,"MS1\0") ne retourne pas 0 (égalité) !!
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 686
strcmp(strp,"MS1\0")
Le "\0" est superflue. Si cela ne marche pas. Il faut savoir qu'en fait fgets (comme gets()) stocke, s'il y a la place, le caractère '\n' émis lorsque tu tapes sur la touche entrée.
Il faut donc l'enlever.
Tu peux utiliser la routine de saisie :
char *saisie (char *strp, const int sz, const FILE* fp) {
     char *s = fgets (strp, sz, fp);
     if ( s != NULL) {
          char *p = strchr (strp, '\n');
          if (p != NULL)
               p = '\0';
          else {
               int c;
               while ( (c = getchar ()) != '\n' && c != EOF);
         }
     }
     return s;
}

Note : c'est fait en live, il y a peut-être des coquilles qui se verront à la compil.
A la place, d'utiliser fgets(ch,sizeof (ch), stdin); il te faudra faire : saisie(ch, sizeof ch, stdin); (pour info, les parenthèses sont facultatives autour de la variable pour le sizeof).
De plus, pourquoi souhaites-tu à tout prix passer par la variable strp avec allocation ? Tu peux directement utiliser la variable ch.
Cdlt,
Messages postés
8
Date d'inscription
jeudi 31 janvier 2013
Statut
Membre
Dernière intervention
20 mars 2013

Ok même avec la fonction de saisie le résultat n'a pas changé, je me suis débrouillé avec un ajout du "\n" en comparaison:
#include <string.h>
#include <stdio.h>
#define MAX 255

/***** char *saisie (char *strp, const int sz, const FILE* fp) {
     char *s = fgets (strp, sz, fp);
     if ( s != NULL) {
          char *p = strchr (strp, '\n');
          if (p != NULL)
               p = '\0';
          else {
               int c;
               while ( (c = getchar ()) != '\n' && c != EOF);
         }
     }
     return s;
}   *****/

int main()
{
    char ch[MAX];
    printf("Entrer votre choix\n");
    //saisie(ch, sizeof ch, stdin);
    fgets(ch,sizeof ch, stdin);
    if (strcmp(ch,"MS1\n")==0) printf("Machine en Marche sens 1 \n");
    else if (strcmp(ch,"MS2\n")==0) printf("Machine en Marche sens 2\n");
    else if (strcmp(ch,"ARRET\n")==0) printf("Machine en Arret\n");
    else printf("Mauvais choix\n");
    
getchar();getchar();;
return 0;
}


Merci.
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 686
Oui c'est une méthode. Mais qui ne marchera pas dans tous les cas. Si l'utilisateur frappe une grande chaîne, il n'y aura pas de '\n' dedans.
De plus le buffer ne sera pas vidé si la chaîne est trop grande et cela pourra poser des problèmes pour les prochaines lectures clavier.
En relisant mon code, j'ai trouvé l'erreur.
Ce n'est pas p='\0', mais *p='\0';
Le code donne :
char *saisie (char *strp, const int sz, FILE* fp) { 
     char *s = fgets (strp, sz, fp); 
     if ( s != NULL) { 
          char *p = strchr (strp, '\n'); 
          if (p != NULL) 
               *p = '\0'; 
          else { 
               int c; 
               while ( (c = getchar ()) != '\n' && c != EOF); 
         } 
     } 
     return s; 
} 

Et là, ça doit fonctionner :-).
Messages postés
8
Date d'inscription
jeudi 31 janvier 2013
Statut
Membre
Dernière intervention
20 mars 2013

Ah ok maintenant ça marche T bien,
Merci :)