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 :

detection d'erreur sur atoi()


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 855
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 855
    Par défaut detection d'erreur sur atoi()
    Bonjour,

    Je voudrais convertir une chaine ASCII en nombre => donc j'utilise la fonction atoi().
    Le problème est que je ne sais pas comment faire pour détecté s'il y a eu une erreur pendant la conversion (par exemple s'il y a des lettres dans la chaine).

    Comment dois-je faire ?

    Remarque : compîlo => version modifié de gcc pour µControlleur PIC32

  2. #2
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Salut,

    Il faut utiliser une autre fonction, sscanf par exemple. Le résultat est le nombre de variables scannées avec succès, tu peux donc t'en servir comme détection d'erreur.

    A+

    Pfeuh

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #include <stdio.h>
     
    int main(int argc, char **argv)
    {
        int value;
        int result;
        char textinput1[] = "12345";
        char textinput2[] = "blabla";
        result = sscanf(textinput1, "%i", &value);
        if(result != 1)
        {
            printf("erreur\n");
        }
        else
        {
            printf("%i\n", value);
        }
        result = sscanf(textinput2, "%i", &value);
        if(result != 1)
        {
            printf("erreur\n");
        }
        else
        {
            printf("%i\n", value);
        }
     
     
        return 0;
    }

  3. #3
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Bonjour,

    Pourquoi ne pas utiliser strtol, qui est faite pour ca, plutot que sscanf, qui est beaucoup plus complexe a manier ?


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    long ma_valeur;
    /* --- */
    errno = 0;
    ma_valeur = strtol (chaine, (char**)NULL, 10);
     
    if ((errno == ERANGE && (ma_valeur == LONG_MAX || ma_valeur == LONG_MIN)) ||
       (errno != 0 && val == 0))
    {
    /* traitement de l'erreur */
    }
    else
    {
    /* suite du code */
    }
    /* ... */
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 855
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 855
    Par défaut
    ok, merci pour vos reponses

  5. #5
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Pourquoi ne pas utiliser strtol, qui est faite pour ca, plutot que sscanf, qui est beaucoup plus complexe a manier ?
    Parce que sur son µC, il veut peut-être passer par des int et non des long, il n'y a pas forcément beaucoup de ram. Et il me semble d'autre part que errno n'est pas sûr si on utilise des threads, ce qui est enviseageable sur les gros µC Microchip. En fait, c'est surtout parce que je ne connaissais pas strtol. Qui a des avantages certains, dont le choix de la base.

  6. #6
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Et moi je n'avais pas lu qu'il etait sur micro-controlleur... Tout va bien
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 855
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 855
    Par défaut
    Citation Envoyé par pfeuh Voir le message
    Salut,

    Il faut utiliser une autre fonction, sscanf par exemple. Le résultat est le nombre de variables scannées avec succès, tu peux donc t'en servir comme détection d'erreur.

    A+

    Pfeuh

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #include <stdio.h>
     
    int main(int argc, char **argv)
    {
        int value;
        int result;
        char textinput1[] = "12345";
        char textinput2[] = "blabla";
        result = sscanf(textinput1, "%i", &value);
        if(result != 1)
        {
            printf("erreur\n");
        }
        else
        {
            printf("%i\n", value);
        }
        result = sscanf(textinput2, "%i", &value);
        if(result != 1)
        {
            printf("erreur\n");
        }
        else
        {
            printf("%i\n", value);
        }
     
     
        return 0;
    }
    en faite cette methode ne fonctionne pas => si je rentre "1a", ça me trouve un nombre ("a1" => ne donne pas de nombre par contre)
    Y a t-il quand même une solution avec sscanf ?

  8. #8
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    cette methode ne fonctionne pas
    Elle ne fait pas ce que tu voudrais qu'elle fasse, c'est différent. Elle parse ta chaine jusqu'au premier caractère non numérique. Ça permet de sortir plusieurs données d'une même chaine. Le premier caractère rencontré dans ton cas est un '1', elle a donc bien une chaine qu'elle peut évaluer jusqu'au deuxième caractère 'a'.

    Citation Envoyé par boboss123 Voir le message
    Y a t-il quand même une solution avec sscanf ?
    il y a la solution proposée par quetzacoatl. Sinon, tu peux rajouter un test avant le sscanf que je te propose ci-dessous, isnumerictext Du coup, tu auras vu au moins une fois des tests unitaires.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    #include <stdlib.h>
    #include <ctype.h>
    #include <assert.h>
    #include <stddef.h>
     
    typedef struct
    {
        char* pattern;
        int result;
    } test_record;
     
    test_record test_datas[] =
    {
        {"a1", 0},
        {"1a", 0},
        {"123", 1},
        {"123 ", 0},
        {"", 0},
        {" 123", 0},
        {NULL, 0}
    };
     
    int isnumerictext(char* text)
    {
        if(*text=='\0') return 0;
        if (!isdigit(*text)) return 0;
        while(1)
        {
            if(*text=='\0') return 1;
            if (!isdigit(*text)) return 0;
            text++;
        }
    }
     
    int main(int argc, char **argv)
    {
        test_record* record_ptr =  test_datas;
        while(record_ptr->pattern != NULL)
        {
            printf("\"%s\" : %i\n", record_ptr->pattern, record_ptr->result);
            assert(isnumerictext(record_ptr->pattern)==record_ptr->result);
            record_ptr++;
        }
        return 0;
    }

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 855
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 855
    Par défaut
    merci pour vos réponses


    sinon, j'ai trouvé encore une autre solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    unsigned int val;
    int result;
    unsigned char str[2];
    result = sscanf(buf, "%u%1s", &val, str);
    if(result  != 1){
       // erreur
    }
    => par contre, c'est normal que la chaine "-1" me renvoi la valeur 4294967295 (avec result = 1) ? c'est un bug de ma lib ?

  10. #10
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    C'est normal, tu as demandé à formater en unsigned (%u) le nombre est donc -1 codé en 32 bits à savoir 4294967295. car 0xffffffff représente 4294967295 en non signé et -1 en signé

  11. #11
    Membre expérimenté Avatar de quetzacoatl
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 168
    Par défaut
    tu peux essayer de faire(non testé):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int nbr_char;
    ....
    result = sscanf(textinput1, "%i%n", &value,&nbr_char);
    if(nbr_char!=strlen(textinput1))
    {
       puts("Erreur: ...");
       return -1;
    }

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

Discussions similaires

  1. Detection d'erreur sur LOAD DATA LOCAL INFILE
    Par cquilgars dans le forum Administration
    Réponses: 3
    Dernier message: 01/08/2013, 17h51
  2. [VBS] Erreur sur "AddWindowsPrinterConnection"
    Par Admin dans le forum VBScript
    Réponses: 5
    Dernier message: 27/03/2004, 16h15
  3. Erreur sur serveur lié
    Par k-lendos dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 18/03/2004, 15h21
  4. []Erreur sur second emploi collection binding
    Par jacma dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 08/03/2004, 18h02
  5. Erreur sur le TNSListener après installation de 9iAS
    Par Patmane dans le forum Installation
    Réponses: 4
    Dernier message: 04/02/2004, 11h16

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