IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

problème pour gérer une exception


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Assistant de vie
    Inscrit en
    Mars 2008
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Assistant de vie
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2008
    Messages : 10
    Par défaut problème pour gérer une exception
    Bonjour,

    j’essaie de transformer un char en double, mais comme il peux y avoir des lettres dans mon char, je veux faire un try except.
    mais j'ai vu qu'en c il n'y a pas de gestion d'exception, mais comme je compile avec gcc, peut etre que gcc prend pour code pour du c++
    il me semble avoir appris en cours qu'on utilisait try except et non try catch, mais d'après mes recherches il faut utiliser try catch

    voici mon extrait de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    char *valeur_entry = gtk_editable_get_text(GTK_EDITABLE(widget));
            try:
            	{
    		double a = atof(valeur_entry);
    		g_print("Valeur : %lf\n", a);
            	}
            catch: // or except
            	{
            	g_print("TRY : valeur non numérique\n");
            	}
    j'aimerai aussi avoir l'info du type d'erreur du try
    d'avance merci

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 476
    Par défaut
    Bonjour,

    Citation Envoyé par fanfantasy7 Voir le message
    Bonjour,

    j’essaie de transformer un char en double, mais comme il peux y avoir des lettres dans mon char, je veux faire un try except.
    mais j'ai vu qu'en c il n'y a pas de gestion d'exception,
    En effet. En C, tu restes « très proche de la machine » et il te faut donc gérer toi-même l'allocation/libération de la mémoire et les erreurs potentielles.
    C'est généralement à la fonction de te l'indiquer et c'est dans le manuel de chacune de ces fonctions qu'il faut aller puiser pour savoir comment elle le fait.

    Donc, pas de système d'exception à proprement parler (certains l'implémentent quand même à l'aide d'un goto, qui est d'ailleurs le principal usage que l'on en fait encore en C, mais on ne relancera surtout pas le débat ici…)

    Généralement, la valeur renvoyée peut prendre une valeur spéciale (pointeur NULL, zéro, booléen, code spécial) qui te permet de reconnaître une erreur. C'est aussi le cas lorsque la fonction n'est utilisée que pour ses effets de bords, c'est-à-dire que l'on utilise la fonction que comme un sous-programme qui va agir sur un ensemble de données quelque part et dont la valeur de retour ne servira justement qu'à renseigner sur le bon déroulement de l'opération.

    Ce n'est pas le cas de atof qui en soi est une vraie fonction, dans le sens où c'est à la fois une « fonction pure » (ie: sans effet de bord) et où la valeur qu'elle renvoie correspond directement à ce que tu lui passes en paramètre (avec un bémol : tu lui passes un pointeur sur une chaîne mais comme le contenu de cette chaîne peut être modifié, tu peux obtenir différents résultats avec un même paramètre d'entrée selon ce contenu).

    Et « malheureusement », tu as choisi une fonction qui ne te permet pas de savoir si une erreur s'est produite car elle considère que les données sont fiables. Selon la page de manuel :

    Citation Envoyé par man

    DESCRIPTION
    La fonction atof() convertit le début de la chaîne pointée par nptr en un type double. Le comportement est le même que

    strtod(nptr, NULL);

    à la différence que atof() ne détecte pas les erreurs.
    Je t'invite donc à t'orienter dès à présent vers strtod().


    mais comme je compile avec gcc, peut etre que gcc prend pour code pour du c++
    Non. Pas ici. « gcc » signifiait initialement « GNU C Compiler » parce qu'il découlait directement de la commande UNIX originelle « cc » mais est devenu par la suite « GNU Compiler Collection » parce que le projet a construit une base commune à différents compilateurs pour différents langages tels que C, C++, Fortran ou même Java.

    Cela dit, le compilateur C reste « gcc » et le compilateur C++ est « g++ ». Il se peut qu'en l'absence de flags de configuration stricte, ton compilateur tolère certaines syntaxes héritées d'un langage ou de l'autre et surtout de certains niveaux de la norme (C99, C++11, etc.) mais tu ne devrais pas pouvoir compiler directement du C++ formel avec le compilateur C.

    il me semble avoir appris en cours qu'on utilisait try except et non try catch, mais d'après mes recherches il faut utiliser try catch
    Tu confonds avec Python.

    • En C : pas d'exception ;
    • En C++ : try { } catch()
    • En Javascript, en Java et dans beaucoup de langages qui suivent chronologiquement l'apparition de ceux-ci : try { } catch() également ;
    • En Python : try: except:


    voici mon extrait de code
    Comme expliqué, pas d'exception en C pur, et pas de code d'erreur renvoyé par atof() qui considère les données comme fiables.

    La fonction strtod() fonctionne un peu différemment et on peut lire dans le manuel que :

    Citation Envoyé par man
    VALEUR RENVOYÉE
    Ces fonctions renvoient la valeur convertie si c'est possible.

    Si endptr n'est pas NULL, un pointeur sur le caractère suivant le dernier caractère converti est stocké dans l'emplacement pointé par endptr.

    Si aucune conversion n'est possible, la fonction renvoie zéro, et (à moins que endptr soit NULL) la valeur de nptr est stockée dans endptr.

    Si la valeur convertie déclenche un débordement (overflow), la fonction renvoie plus ou moins HUGE_VAL, HUGE_VALF ou HUGE_VALL (en fonction du type de retour et du signe de
    la valeur) et errno contient ERANGE.

    Si la valeur convertie déclenche un débordement inférieur (underflow), la fonction renvoie une valeur de grandeur inférieure à DBL_MIN, FLT_MIN ou LDBL_MIN et errno
    contient ERANGE.

    Cela signifie que :
    • Dans tous les cas, la fonction renvoie la valeur lue ou zéro si elle en est incapable ;
    • Une valeur non nulle est forcément valide mais on ne sait pas si un zéro est le fruit d'une lecture légitime ou d'une erreur ;
    • Il y a un code déposé dans errno et une valeur spéciale renvoyée en cas de débordement, c'est-à-dire si la valeur est lue correctement mais ne tient pas dans un float ou un double ;
    • Dans tous les cas (et donc dans ceux qui nous intéressent), strtod() attend en argument un « pointeur vers un pointeur », pour y déposer l'emplacement dans la chaîne où il s'est arrêté.


    Une manière « simple » dans un premier temps, même si cela n'a rien d'idéal, est de vérifier si le caractère pointé par le pointeur de retour est bien un zéro, ou '\0'. Comme ce zéro est le marqueur d'une fin de chaine en langage C, cela te permettra de vérifier que la fonction a bien lu la chaîne en entier si tu l'y trouves.

    Il y a bien sûr beaucoup de cas légitimes à s'arrêter avant la fin mais dans la situation qui t'occupe, cela reste un moyen facile de couvrir 99% des cas d'erreur.

  3. #3
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Bonsoir,

    En programmation C, il existe des fonctions standards qui permettent de convertir la partie initiale d'une chaîne de caractères pointée en nombre à virgule flottante (double), telles que strtod(), strtof() et strtold() (comme dis par obsidian) . Cependant, il est important de lire attentivement la documentation de ces fonctions, car certaines d'entre elles ne détectent pas nécessairement les erreurs de conversion. Il faut donc effectuer les vérifications appropriées pour s'assurer que la conversion s'est correctement déroulée et gérer les cas d'erreurs le cas échéant.


    Aussi en langage C pur, la gestion des exceptions n'est pas native et requiert l'utilisation d'une bibliothèque externe. Par exemple, une extension Microsoft du langage C permet de gérer les exceptions de manière similaire au C++. Il est également possible d'utiliser une bibliothèque comme POSIX pour implémenter la gestion des exceptions à l'aide de macros telles que posix_error_set(), posix_error_throw() et posix_error_catch().


    Et oui, lors de la compilation avec GCC, le compilateur reconnaît les constructions try/catch comme du C++. Cependant, si vous maîtrisez déjà le C++, il peut être préférable de continuer dans ce langage car la syntaxe correcte est try/catch et non try/except comme en Python. Sinon, une alternative en C est d'implémenter vous-même la gestion des exceptions en utilisant setjmp/longjmp ou des extensions/bibliothèques telles que POSIX.


    Pour votre code, je vois effectivement deux erreurs (d'implémentation et de gestion d'erreur).



    1. L'utilisation incorrecte des exceptions, car la fonction atof() lève des erreurs via errno plutôt qu'un type générique. Il faut catcher spécifiquement sur errno.
    2. Une gestion trop générique de l'erreur dans le bloc catch, alors qu'errno permet de connaître précisément l'origine de l'erreur. Il faut implémenter des messages et actions dédiés selon chaque code d'erreur possible.


    Pour la suite, c'est à vous de faire le nécessaire.
    à bientôt

  4. #4
    Membre averti
    Homme Profil pro
    Assistant de vie
    Inscrit en
    Mars 2008
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Assistant de vie
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2008
    Messages : 10
    Par défaut merci
    Merci beaucoup pour vos réponses très détaillées.
    en effet strtod fonctionne bien.

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par fanfantasy7 Voir le message
    mais j'ai vu qu'en c il n'y a pas de gestion d'exception, mais comme je compile avec gcc, peut etre que gcc prend pour code pour du c++
    Soit tu fais du C, soit tu fais du C++. Les deux langages, bien qu'ayant une source commune, sont devenus maintenant trop différents pour être associés. Tu ne peux donc pas dire "je fais du C mais j'y intègre des trucs C++". D'ailleurs si ton source se termine par ".c" c'est le compilateur C qui sera utilisé et lui il n'acceptera pas les instructions C++.

    Sinon tu as sscanf() qui peut te rendre aussi pas mal de services.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Si erreur / try catch / swith pour gérer une exception
    Par Invité dans le forum SAS Base
    Réponses: 8
    Dernier message: 07/12/2017, 13h09
  2. Probleme pour capter une exception
    Par Krishna dans le forum Bibliothèques
    Réponses: 2
    Dernier message: 12/01/2009, 21h44
  3. Réponses: 8
    Dernier message: 30/11/2007, 14h15
  4. Problème pour intercepter une exception
    Par kurul1 dans le forum C++Builder
    Réponses: 3
    Dernier message: 06/04/2007, 14h14
  5. lever une EXCEPTION pour 2 blocs séparés
    Par atruong dans le forum Oracle
    Réponses: 2
    Dernier message: 05/05/2006, 10h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo