Débutant need Help en C

Débutant need Help en C - C - Programmation

Marsh Posté le 04-05-2010 à 00:20:19    

Bonjour à tous,
 
J'ai un soucis avec un programme que je suis en train de développer. Je vous explique la situation :
 
Je cherche à créer un menu avec des choix de type "int" et je switch en fonction du choix effectué.
Le programme fonctionne bien quand on saisi un chiffre. Malheureusement, dès qu'on saisi autre chose que du "int", le programme bug et tourne en boucle, ce qui est fort gênant...
 
Je vous colle le code que j'ai fait :
 

Code :
  1. void menu_principal()
  2. {
  3.     int choix = 0;
  4.     do
  5.     {
  6.         printf("*--------------------------------------------------------------*\n" );
  7.         printf("|                                                              |\n" );
  8.         printf("|                        MENU PRINCIPAL                        |\n" );
  9.         printf("|                                                              |\n" );
  10.         printf("|    1 - Effectuer une conversion                              |\n" );
  11.         printf("|    2 - Ajouter une devise                                    |\n" );
  12.         printf("|    3 - Mettre a jour une devise                              |\n" );
  13.         printf("|    4 - Supprimer une devise                                  |\n" );
  14.         printf("|    5 - Sauvegarder les changements effectues                 |\n" );
  15.         printf("|    0 - Retour au menu d'accueil                              |\n" );
  16.         printf("|                                                              |\n" );
  17.         printf("*--------------------------------------------------------------*\n" );
  18.         printf("\n" );
  19.         printf("Votre choix : " );
  20.         scanf("%d", &choix);
  21.         if (choix < 0 || choix >5)
  22.         {
  23.             printf("Erreur de saisie, veuillez recommencer : " );
  24.             scanf("%d", &choix);
  25.         }
  26.         else
  27.         {
  28.             switch (choix)
  29.             {
  30.                 case 1:
  31.                     menu_conversion();
  32.                 break;
  33.                 case 2:
  34.                     printf("Menu Ajout\n\n" );
  35.                     //menu_ajout();
  36.                 break;
  37.                 case 3:
  38.                     printf("Menu MAJ\n\n" );
  39.                     //menu_maj();
  40.                 break;
  41.                 case 4:
  42.                     printf("Menu Suppr\n\n" );
  43.                     //menu_suppr();
  44.                 break;
  45.                 case 5:
  46.                     printf("Menu Save\n\n" );
  47.                     //menu_save();
  48.                 break;
  49.             }
  50.         }
  51.     } while (choix != 0);
  52. }


 
Je débute en programmation, j'ai suivi les cours disponibles sur le site "Lesiteduzéro"...  
 
Je pense que le problème vient du fait que je lui demande une saisie de type "int". Si on saisir du "char", l'ordinateur ne comprend pas et donc, on se retrouve dans un monde merdique. Mais je ne saurai pas comment résoudre ce souci, donc si des personnes s'y connaissent, merci de m'éclairer ! :)


Message édité par Bubu92 le 19-05-2010 à 17:31:57
Reply

Marsh Posté le 04-05-2010 à 00:20:19   

Reply

Marsh Posté le 04-05-2010 à 06:06:36    

Salut,
 
Même si elle peut sembler simple et efficace, je te conseille vivement d'éviter la fonction scanf pour de nombreuses raisons. Ces raisons sont entre autres évoquées sur le site du zero, tutorial que tu peux lire ici:
 
http://www.siteduzero.com/tutoriel [...] fgets.html
 
Voici ma solution, certainement pas parfaite mais fonctionnelle ;)
 

Code :
  1. #include <stdio.h>
  2. # define BUFFER_SIZE 16
  3.  
  4. void purge(void)
  5. {
  6.    int c;
  7.  
  8.    while ((c = getchar()) != '\n' && c != EOF);
  9. }
  10.  
  11. void menu_principal()
  12. {
  13.    int choix = 0;
  14.    char buffer[BUFFER_SIZE];
  15.    do
  16.    {
  17.        printf("*--------------------------------------------------------------*\n" );
  18.        printf("|                                                              |\n" );
  19.        printf("|                        MENU PRINCIPAL                        |\n" );
  20.        printf("|                                                              |\n" );
  21.        printf("|    1 - Effectuer une conversion                              |\n" );
  22.        printf("|    2 - Ajouter une devise                                    |\n" );
  23.        printf("|    3 - Mettre a jour une devise                              |\n" );
  24.        printf("|    4 - Supprimer une devise                                  |\n" );
  25.        printf("|    5 - Sauvegarder les changements effectues                 |\n" );
  26.        printf("|    0 - Retour au menu d'accueil                              |\n" );
  27.        printf("|                                                              |\n" );
  28.        printf("*--------------------------------------------------------------*\n" );
  29.        printf("\n" );
  30.        printf("Votre choix : " );
  31.        fgets(buffer, BUFFER_SIZE, stdin);
  32.        choix = atoi(buffer);
  33.        if (choix == 0 && buffer[0] != '0')
  34.        {
  35.            choix = -1;
  36.            printf("Erreur de saisie, veuillez recommencer : \n\n" );
  37.        }
  38.        else if (choix < 0 || choix > 5)
  39.            printf("Erreur de saisie, veuillez recommencer : \n\n" );
  40.        else
  41.        {
  42.            switch (choix)
  43.            {
  44.                case 1:
  45.                    printf("Menu Ajout\n\n" );
  46.                    //menu_conversion();
  47.                break;
  48.                case 2:
  49.                    printf("Menu Ajout\n\n" );
  50.                    //menu_ajout();
  51.                break;
  52.                case 3:
  53.                    printf("Menu MAJ\n\n" );
  54.                    //menu_maj();
  55.                break;
  56.                case 4:
  57.                    printf("Menu Suppr\n\n" );
  58.                    //menu_suppr();
  59.                break;
  60.                case 5:
  61.                    printf("Menu Save\n\n" );
  62.                    //menu_save();
  63.                break;
  64.            }
  65.        }
  66.        if (strlen(buffer) == BUFFER_SIZE - 1)
  67.            purge();
  68.    } while (choix != 0);
  69. }
  70.  
  71. int     main()
  72. {
  73.        menu_principal();
  74.        return (0);
  75. }


 
Je t'explique le principe vite fait: Quand un utilisateur rentre une donnée, elle est toujours de type char *. C'est à dire que quelque soit l'entrée utilisateur, même si c'est un nombre, tu ne pourras récupérer cette entrée que sous forme d'un char * qui contient ce qui t'intéresse.
 
Toi tu le veux en int. Tu as un char *, c'est balot :o Tu remarqueras qu'effectivement scanf te permettait de récupérer ET de transformer le char * en int. Très pratique, oui mais piège. Je suis très loin d'être un expert en C, mais je n'aime pas du tout scanf. Donc ce que je fais dans le code, c'est de faire le job de scanf mais à la main.
 
D'abord je récupère l'entrée utilisateur avec fgets. fgets prend trois paramètres : Un buffer (la zone ou va être stocké ce qu'a tapé l'utilisateur), la taille de ce buffer (C ne peut pas le deviner tout seul ;)) et le file descriptor a partir duquel je veux récupérer mes données. Si tu n'as pas vu les file descriptors, saches simplement que l'entrée utilisateur = stdin. (Il faut inclure <stdio.h> pour éviter les erreurs de compilation)
 
Ensuite je fais un atoi de ce buffer, que je récupère dans la variable nommée choix. Seul problème: Si notre buffer contenait un truc pas convertible en nombre (par exemple si l'utilisateur a tapé efjdsijfisj au lieu de 0, 1, 2...) atoi renverrait le code d'erreur "0". Et alors, comment faire pour différencier le 0 qui aurait pu être entré par l'utilisateur du 0 qui signifie "Attention, erreur !" ?
 
La solution la plus simple (pas forcément la meilleure, comme je t'ai dit précédemment je suis pas un expert :jap: ), c'est de regarder quel est le premier caractère de notre buffer. Si le premier caractère n'est pas 0 mais que la variable choix est a 0, cela veut dire qu'atoi a renvoyé une erreur => On met choix a -1 pour éviter de sortir de la boucle et on affiche le message d'erreur.
 
Le reste c'est ton code. Le strlen(buffer) == BUFFER_SIZE - 1 permet de savoir si l'utilisateur a rentré trop de données en entrée. Si c'est le cas, on "vide" l'entrée avant de repartir au début (ceci évitant notamment une boucle infinie :))
 
Bref je sais que pas mal de trucs que je dis peuvent paraître plus qu'obscurs, mais c'est pas si compliqué au final :D Au pire continues d'apprendre avant de vouloir gérer ces cas, c'est pas forcément facile au début :D


---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010
Reply

Marsh Posté le 04-05-2010 à 18:04:12    

Merci pour ton aide WiiDS ! :)
 
Je vais sûrement être amené à re-poster ici vu la super soluce que tu m'as filé ! :whistle:

Reply

Marsh Posté le 19-05-2010 à 17:44:45    

Bonjour à tous,
 
Je fais suite à mon premier message de demande d'aide ; je suis à nouveau dans le besoin par rapport à mon application en C.
 
Petit explication : je cherche à créer une application de conversion monétaire. Je veux dans un premier temps écrire dans un fichier Texte des devises et ensuite pouvoir les récupérer pour effectuer les conversions.
 
Pour cela, j'ai besoin d'écrire dans le fichier de cette façon :
 
Numéro "d'identifiant" de la ligne, Nom de la Devise, Pays associé, Montant, Date du jour de la saisie
 
Ce qui pourrait se présenter comme ceci :
 
01, Dollar, USA, 0.80, 19/05/2010
02, Euro, Europe, 1.00, 19/05/2010
03, Yen, Japon, 15.58, 19/05/2010
Etc...

 
J'ai 3 problèmes face à moi :
1/ Comment faire comprendre à l'ordinateur que je veux écrire à chaque début de ligne ce numéro d'identifiant en incrémentation
2/ Comment lui faire comprendre que je veux un retour à la ligne à chaque fin de mes saisies
3/ Comment enregistrer de façon automatique la date système
 
 
Voilà, j'ai plein d'autres problèmes dans ma liste (:D) mais ceux-ci sont les principaux actuellement... S'il y a des personnes qui savent faire ceci sans trop se casser la tête, je leur serai reconnaissant de m'éclairer sur le sujet !
 
Merci d'avance.

Reply

Marsh Posté le 19-05-2010 à 18:00:52    

Bubu92 a écrit :

1/ Comment faire comprendre à l'ordinateur que je veux écrire à chaque début de ligne ce numéro d'identifiant en incrémentation

C'est a toi de maintenir une variable numéro de ligne dans ton programme de lecture écriture

Bubu92 a écrit :

2/ Comment lui faire comprendre que je veux un retour à la ligne à chaque fin de mes saisies

print("blabla\n" );

Bubu92 a écrit :

3/ Comment enregistrer de façon automatique la date système

Utiliser les fonctions standard de la librairie, dans <time.h>
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 19-05-2010 à 19:29:07    

J'ai fait un bout de code avec l'aide d'un ami mais il y a quelques erreurs, je vous affiche le machin :

 


Code :
  1. void fonction_ajout()
  2. {
  3.     FILE *fichier = NULL; // Initialisation du pointeur "fichier" vers FILE à NULL
  4.     int choix = 0;
  5.     char devise[25];
  6.     char pays[25];
  7.     float montant = 0;
  8.     int i = 0;
  9.     fichier = fopen("liste.txt", "w" ); // Ouverture du fichier
  10.     if (fichier != NULL) // On teste que le fichier existe bien
  11.     {
  12.         for (i=0; i<MAX_entree; i++)
  13.         {
  14.             printf("Saisir le nom de la devise : " ); // Saisie du nom de la devise
  15.             scanf("%s", devise);
  16.             printf("\nSaisir le pays en association avec la devise : " ); //Saisie du pays
  17.             scanf("%s", pays);
  18.             printf("\nSaisir le montant de la devise : " ); // Saisie du montant
  19.             scanf("%f", &montant);
  20.             printf("\n\nVous avez saisi : %s, %s, %f.", devise, pays, montant); // On affiche les valeurs saisies...
  21.             printf("\nVous confirmez ? 1 = Oui / 0 = Non" ); // ... et on demande de confirmer.
  22.             scanf("%d", &choix);
  23.             if (choix == 0) // Si on ne confirme pas...
  24.             {
  25.                 printf("\nAnnulation...\n" );
  26.             }
  27.             else // Si on confirme, on écrit dans le fichier
  28.             {
  29.                 fprintf("%d, %s, %s, %f, %s\n", i, (devise+i), (pays+i), (montant+i), date());
  30.             }
  31.         }
  32.         fclose(fichier); // On ferme le fichier
  33.     }
  34.     else // Si le fichier n'existe pas, on affiche un message d'erreur...
  35.     {
  36.         printf("Impossible d'ouvrir le fichier...\n\n" );
  37.     }
  38. }
 


Avec ce code, mon compilateur m'indique trois erreurs, dont deux pour la ligne "for (i=0; i<MAX_entree; i++)" et une pour la date :
- 'MAX_entree' undeclared (first use in this function)
- (Each undeclared identifier is reported only once for each function is appears in.)
- Syntax error before "date"

Message cité 1 fois
Message édité par Bubu92 le 19-05-2010 à 19:29:45
Reply

Marsh Posté le 19-05-2010 à 20:38:06    

Bubu92 a écrit :

- 'MAX_entree' undeclared (first use in this function)

Le message d'erreur est explicite.

Bubu92 a écrit :

- Syntax error before "date"

il y a pas de fonction date() dans la librairie C standard.
A+,
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 19-05-2010 à 21:26:03    

J'ai ajouté "#define MAX_entree 200", le message d'erreur n'apparait plus.
J'ai mis "#include <time.h>" mais le message d'erreur est toujours présent...

Reply

Marsh Posté le 20-05-2010 à 00:57:52    

fprintf ne prend pas un file descriptor en premier paramètre ?
 
Je veux pas dire de bêtises mais je verrais plus un truc comme ça:
 

Code :
  1. fprintf(stdout, "%d, %s, %s, %f, %s\n", i, (devise+i), (pays+i), (montant+i), date());


 
Avec #include <stdio.h> évidemment


---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010
Reply

Marsh Posté le 20-05-2010 à 06:55:31    

Bubu92 a écrit :

J'ai ajouté "#define MAX_entree 200", le message d'erreur n'apparait plus.


Je te rajoute une question mais... tu fais comment pour sortir si tu veux pas te pastiller 200 saisies à chaque fois ?


---------------
If you think it could look good, then I guess it should
Reply

Marsh Posté le 20-05-2010 à 06:55:31   

Reply

Marsh Posté le 20-05-2010 à 14:36:27    

Bubu92 a écrit :

J'ai mis "#include <time.h>" mais le message d'erreur est toujours présent...

Et ça va changer quoi?
S'il y a pas de fonction date(), il y a pas de fonction date(). Ajouter un header ne changera rien a ce fait.
Faire "#include <time.h>" est une bonne chose, mais encore faut il en lire la doc et utiliser les fonctions de cette librairie, en l'occurence time, localtime et strftime.
A+,
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 21-05-2010 à 19:36:38    

WiiDS a écrit :

fprintf ne prend pas un file descriptor en premier paramètre ?
 
Je veux pas dire de bêtises mais je verrais plus un truc comme ça:
 

Code :
  1. fprintf(stdout, "%d, %s, %s, %f, %s\n", i, (devise+i), (pays+i), (montant+i), date());


 
Avec #include <stdio.h> évidemment


 
Ou plus simplement

Code :
  1. printf("%d, %s, %s, %f, %s\n", i, devise+i, pays+i, montant+i, date());

[:spamafote]

Message cité 1 fois
Message édité par Sve@r le 22-05-2010 à 11:47:03

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 22-05-2010 à 03:18:00    

Sve@r a écrit :


 
Ou plus simplement

Code :
  1. printf("%d, %s, %s, %f, %s\n", i, (devise+i), (pays+i), (montant+i), date());

[:spamafote]


Aussi [:ddr555]


---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed