Allocation et de comparaison des chaines de caractères

Résolu/Fermé
Delared Messages postés 8 Date d'inscription jeudi 31 janvier 2013 Statut Membre Dernière intervention 20 mars 2013 - 2 févr. 2013 à 09:11
Delared Messages postés 8 Date d'inscription jeudi 31 janvier 2013 Statut Membre Dernière intervention 20 mars 2013 - 2 févr. 2013 à 18:29
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.
A voir également:

2 réponses

Utilisateur anonyme
2 févr. 2013 à 11:29
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
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
2 févr. 2013 à 12:39
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...
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
2 févr. 2013 à 12:47
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
Delared Messages postés 8 Date d'inscription jeudi 31 janvier 2013 Statut Membre Dernière intervention 20 mars 2013
Modifié par Delared le 2/02/2013 à 16:01
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é) !!
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
2 févr. 2013 à 16:30
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,
0
Delared Messages postés 8 Date d'inscription jeudi 31 janvier 2013 Statut Membre Dernière intervention 20 mars 2013
2 févr. 2013 à 17:27
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.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
Modifié par fiddy le 2/02/2013 à 17:46
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 :-).
0
Delared Messages postés 8 Date d'inscription jeudi 31 janvier 2013 Statut Membre Dernière intervention 20 mars 2013
2 févr. 2013 à 18:29
Ah ok maintenant ça marche T bien,
Merci :)
0