Menu

Langage C, fonction sscanf et pointeur [Résolu/Fermé]

- - Dernière réponse :  lunebleue - 23 mars 2011 à 00:46
Bonjour,
je suis en train d'écrire un programme en langage C et en fait, mon programme affiche un menu d'option sur l'entrée standard et récupère le choix de l'utilisateur.
Mais j'ai de gros soucis pour gérer les options qui n'existent pas, parce que j'aimerai que dans ce cas, le programme ne renvoie aucune erreur mais réaffiche simplement le menu en attendant une autre réquête...
Alors j'ai réalisé à l'aide de switch et de if un menu qui fonctionne mais qui à mon sens est loin d'être propre... J'ai donc voulu réaliser de petites fonctions qui réalisent en dehors de ce menu la validation de la chaine passée en argument.

Voici mon code de menu (qui fonctionne)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "def.h"

/* Fonction d'affichage du menu sur la sortie standard */
void menu()
{
  printf("\n");
  printf("Commandes proposees a l'utilisateur : \n") ;
  printf("\tf <fichier> 	affiche l'arbre de filiation complet des processus\n") ;
  printf("\tn <pid>  	affiche l'arbre de filiation a partir du processus n° pid\n") ;
  printf("\taf <fichier>  	affiche la structure interne de l'arbre n-aire de filiation complet des processus\n") ;
  printf("\tan <pid>  	affiche la structure interne de l'arbre n-aire de filiation des processus a partir du processus n0 pid\n") ;
  printf("\tq  		quitte l'application\n") ;
}



int main(int argc, char *argv[])
{
  char rep[1000] ;
  char* fichier;	/* variable contenant le chemin d'un éventuel fichier à utiliser */
  char* pid_ch;
  int pid;		/* variable contenant le numéro du processus à utiliser */
  char* fff;
  int valide;
  menu() ;
  do
    {
      printf("Votre choix : ") ;
      fgets(rep, 1000, stdin) ;

      switch (rep[0])
        {
	/* Choix : quitter l'application */
        case 'q' :
	  if(rep[1]!='\n')
	    {
	      menu();
	    }
          break ;   
     
	/* Choix :  affiche l'arbre de filiation complet des processus */
	case 'f' :
	  /* Remarque 1 : on s'assure qu'un caractère espace est bien entré entre l'option f et le nom du fichier à traiter */
	  valide = choixF(rep,fff);
	  printf("choix ok : %d\n",valide);
	  printf("nom fichier : %s\n",fff);
	  if(rep[1]!=' ')
	    {
	      menu();
	      break;
	    }
	  sscanf(rep,"f %a[a-zA-Z0-9./\\_~-]\n",&fichier);
	  func_f(fichier);
	  
          break ;   
     
	/* Choix :  affiche l'arbre de filiation a partir du processus n° pid */
	case 'n' :
	  /* Cf remarque 1 */
	  if(rep[1]!=' ')
	    {
	      menu();
	      break;
	    }

	  pid_ch = '\0';
	  sscanf(rep, "n %a[0-9]", &pid_ch);
	  if(pid_ch != '\0'){
		sscanf(pid_ch, "%d", &pid);
	  }
          break ;        

	case 'a' :
	  switch (rep[1])
	    {
	      /* Choix :  affiche la structure interne de l'arbre n-aire de filiation complet des processus */
	      case 'f' :
		/* Cf remarque 1 */
		if(rep[2]!=' ')
	    	{
	           menu();
	      	   break;
	    	}
		printf("je suis dans af\n");
	      break;

	      /* Choix :  affiche la structure interne de l'arbre n-aire de filiation des processus a partir du processus n0 pid */
	      case 'n' :
		/* Cf remarque 1 */
		if(rep[2]!=' ')
	    	{
	           menu();
	      	   break;
	    	}
		pid_ch = '\0';
	    sscanf(rep, "an %a[0-9]", &pid_ch);
	    if(pid_ch != '\0'){
		sscanf(pid_ch, "%d", &pid);
	  }
		printf("je suis dans %d\n", pid);
	      break;

	      default :
	        menu();
	      break;
	    }
          break ; 
	
	/* Par défaut (mauvaise option) on réaffiche le menu */
	default:
	  menu() ; 
	  break ;
	}
    }
  while (rep[0] != 'q' || (rep[0]=='q' && rep[1]!='\n')) ;

  return(0) ;
}


J'ai voulu commencer par "simplifier" l'option f à l'aide de cette fonction :
int choixF(char rep[], char *fichier){
  /* renvoie '0' si l'option commençant par f est valide
     et fait pointer le pointeur fichier vers le nom du fichier que l'on veut traiter 
     renvoie '1' si l'option commençant par f est non valide (pas d'espace...)*/

  int res;
  res = 1;
  if(rep[1]==' '){
     sscanf(rep,"f %a[a-zA-Z0-9./\\_~-]\n",&f);
     printf("nom f : %s\n",fichier);
     res = 0;   
  }
  return res;
}


Le problème c'est que je ne comprends pas pourquoi (même à l'aide de malloc)quand j'affiche le nom du fichier dans la fonction choixF il me l'affiche correctement mais quand je le fais dans le main il affiche n'importe quoi...

Est ce que quelqu'un pourrait m'expliquer ? et mieux, me dire comment résoudre ce problème ?

D'avance merci

Afficher la suite 

1 réponse

Messages postés
401
Date d'inscription
vendredi 28 janvier 2011
Statut
Membre
Dernière intervention
27 avril 2014
49
0
Merci
Bonjour,
Je crois que c'est une copie de l'adresse qui est utilisée dans la fonction du coup le changement ne se fait pas en dehors alors ça pointe là où ça pointait au départ, là ou le pointeur a été initialisé : s'il est à NULL bah il restera à NULL en dehors de la fonction du coup il faut retourner l'adresse essayez comme ça :
char *choixF(char rep[]){ 
    if(rep[1]==' '){ 
        return &rep[2]; //on retourne l'adresse apres l'espace 
    } 
    return NULL;// sinon on met à null 
} 

et dans le switch :
case 'f' : 
  fichier=choixF(rep); //fichier recup le pointeur &rep[2] si y a l'espace 
  if(fichier!=NULL)//donc si n'est pas null c'est ok 
  { 
    printf("nom fichier : %s\n",fichier); 
    func_f(fichier); 
  } 
  else //sinon 
  { 
    menu(); 
  } 
break; 
Cà marche parfaitement ! Même si je trouve vraiment dommage qu'on ne puisse pas affecter mon pointeur directement.
En tout cas, merci beaucoup !