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 :

Récuperer certains caractères particuliers d'une string


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2020
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2020
    Messages : 13
    Par défaut Récuperer certains caractères particuliers d'une string
    Bonjour, je récupère des string au format suivant :

    f int1\int2\int3 int4\int5\int6 int7\int8\int9

    Seuls 'f' et les int1, int 4, int7 sont toujours présents. On n'écrit pas les '\' avec un espace derrière. ( 1\\2 ou 1\2 mais pas 1\\ ou 1\2\)
    Exemple :

    exemple 1: f 1\\3 7 9\0

    exemple 2: f 1 1 10\\11

    exemple 3: f 1\8\9 3\\5 7

    Pour chaque string de ce format, j'aimerais récuperer int1, int4 et int7 d'une manière compacte. J'ai essayé avec sscanf() mais je n'ai pas réussi. Est ce que quelqu'un aurait une idée qui pourrait m'aider ? Merci d'avance pour vos réponses.

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 755
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 755
    Par défaut
    Citation Envoyé par wootwoot Voir le message
    d'une manière compacte. Est ce que quelqu'un aurait une idée qui pourrait m'aider ?
    Compact tu dis

    Tu peux maintenant :
    • faire 1 enum pour toutes les erreurs et 1 procédure pour les afficher (ou 1 fonction qui les converti en chaîne de caractères, généralement en anglais)
    • retourner 1 unsigned char pour la fonction pour savoir si tout s'est bien passé ... et avoir 1 paramètre sortie enum pour l'erreur
    • étoffer les tests
    • remplacer les lignes répétitives par des macros


    Et je précise la machine à états ("state machine" en anglais)/ l'automate est 1 solution + flexible


    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    #include <limits.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
     
    void get_ints(char* str) {
        long int int01, int04, int07;
     
        if (str != NULL) {
            if ((str[0] == 'f') && (str[1] == ' ')) {
                char * substr = strtok ((str + 2), " ");
     
                if (substr != NULL) {
                    char c;
     
                    c = substr[0];
     
                    if ((c >= '0') && (c <= '9')) {
                        int01 = strtol(substr, NULL, 10);
     
                        if ((int01 != LONG_MAX) && (int01 != LONG_MIN)) {
                            substr = strtok (NULL, " ");
     
                            if (substr != NULL) {
                                c = substr[0];
     
                                if ((c >= '0') && (c <= '9')) {
                                    int04 = strtol(substr, NULL, 10);
     
                                    if ((int04 != LONG_MAX) && (int04 != LONG_MIN)) {
                                        substr = strtok (NULL, " ");
     
                                        if (substr != NULL) {
                                            c = substr[0];
     
                                            if ((c >= '0') && (c <= '9')) {
                                                int07 = strtol(substr, NULL, 10);
     
                                                if ((int07 != LONG_MAX) && (int07 != LONG_MIN)) {
                                                    substr = strtok (NULL, " ");
     
                                                    printf("get_ints :\n*) int01: %lu\n*) int04: %lu\n*) int07: %lu\n\n", int01, int04, int07);
                                                } else {
                                                    int01 = int04 = int07 = LONG_MAX;
                                                    printf("get_ints (error) - int07 conversion failed\n\n");
                                                }
                                            } else {
                                                int01 = int04 = int07 = LONG_MAX;
                                                printf("get_ints (error) - int07 is not a number\n\n");
                                            }
                                        } else {
                                            int01 = int04 = int07 = LONG_MAX;
                                            printf("get_ints (error) - int07 substr failed\n\n");
                                        }
                                    } else {
                                        int01 = int04 = int07 = LONG_MAX;
                                        printf("get_ints (error) - int04 conversion failed\n\n");
                                    }
                                } else {
                                    int01 = int04 = int07 = LONG_MAX;
                                    printf("get_ints (error) - int04 is not a number\n\n");
                                }
                            } else {
                                int01 = int04 = int07 = LONG_MAX;
                                printf("get_ints (error) - int04 substr failed\n\n");
                            }
                        } else {
                            int01 = int04 = int07 = LONG_MAX;
                            printf("get_ints (error) - int01 conversion failed\n\n");
                        }
                    } else {
                        int01 = int04 = int07 = LONG_MAX;
                        printf("get_ints (error) - int01 is not a number\n\n");
                    }
                } else {
                    int01 = int04 = int07 = LONG_MAX;
                    printf("get_ints (error) - int01 substr failed (initialization)\n\n");
                }
            } else {
                int01 = int04 = int07 = LONG_MAX;
                printf("get_ints (error) - str doesn't start with f\n\n");
            }
        } else {
            int01 = int04 = int07 = LONG_MAX;
            printf("get_ints (error) - empty parameter\n\n");
        }
    }
     
     
    /*****************************************************************************/
    /***********************************  Main  **********************************/
    /*****************************************************************************/
     
    int main(int argc, char** argv)
    {
        char example01[] = "f 1\\\\3 7 9\\0";
        char example02[] = "f 1 1 10\\\\11";
        char example03[] = "f 1\\8\\9 3\\\\5 7";
     
        char error01[] = "a 1\\8\\9 3\\\\5 7";
        char error02[] = "1\\8\\9 3\\\\5 7";
        char error03[] = "f 1 1 \\\\11";
        char error04[] = "f 1 9\\\\11";
        char error05[] = "f 1 a 9";
     
        get_ints(example01);
        get_ints(example02);
        get_ints(example03);
     
        get_ints(NULL);    // empty parameter
        get_ints(error01); // str doesn't start with f
        get_ints(error02); // str doesn't start with f
        get_ints(error03); // int07 is not a number
        get_ints(error04); // int07 substr failed
        get_ints(error05); // int04 is not a number
     
     
        return EXIT_SUCCESS;
    }

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2020
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2020
    Messages : 13
    Par défaut
    Merci pour ta réponse ! Je suis très décu que cela ne soit pas possible en 2-3 lignes
    Je vais essayer avec un automate, je n'y avais pas pensé.

  4. #4
    Membre Expert
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    667
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 95
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 667
    Par défaut
    Bonjour,

    Dans les exemples donnés :
    Citation Envoyé par wootwoot Voir le message

    exemple 1: f 1\\3 7 9\0

    exemple 2: f 1 1 10\\11

    exemple 3: f 1\8\9 3\\5 7
    Qu'est ce qui correspond à tes int1, int4, et int7 ??

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2020
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2020
    Messages : 13
    Par défaut
    exemple 1: f.....1\\3..... 7....... 9\0

    exemple 2: f.....1.....1.....10\\11

    exemple 3: f......1\8\9...... 3\\5........7

    J'ai mis des points à la place des espaces en espérant que ca soit plus lisible.

    1) int1=1, int4=7, int7=9
    2) int1=1, int4=1, int7=10
    3) int1=1, int4=3, int7=7

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    les 3 ints sont les seuls juste après une espace, ça se fait bien en une seule ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    scanf( "%*[^ ]%d%*[^ ]%d%*[^ ]%d" , &int1 , &int4, &int7 );
    la séquence "%*[^ ]" dit : ignorer tous les caractères non espace
    la séquence "%d" dit : lire un nombre entier potentiellement précédé d'espaces

  7. #7
    Membre Expert
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    667
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 95
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 667
    Par défaut
    Citation Envoyé par foetus Voir le message
    ...
    Pauvre foetus

  8. #8
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2020
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2020
    Messages : 13
    Par défaut
    Merci pour vos réponses, j'essaye ça tout à l'heure.

  9. #9
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 755
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 755
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    scanf( "%*[^ ]%d%*[^ ]%d%*[^ ]%d" , &int1 , &int4, &int7 );
    sauf que la séquence commence par "f " donc plus scanf( "f %d%*[^ ]%d%*[^ ]%d" , &int1 , &int4, &int7 );.


    Citation Envoyé par kaitlyn Voir le message
    Pauvre foetus
    Mon code montre ce qu'il faut faire : d'abord tester "f " et ensuite utiliser 3 fois strtok avec espace pour se positionner sur les entiers et utiliser strtol pour convertir en nombre. (<- 2 liens cplusplus.com en anglais)
    Par contre comme strtol retourne 0L s'il n'y a aucun nombre, il faut à chaque fois tester la présence de chiffre.

    Donc voila, 1 fonction harcodée "4x4 tout terrain" (<- qu'on ne peut pas prendre en défaut si elle est correctement codée) avec toutes les erreurs précises ... pas comme, par exemple, 1 expression régulière qui plante sans savoir ce qu'il ne va pas

  10. #10
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2020
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2020
    Messages : 13
    Par défaut
    Pour l'instant j'ai mis cette solution dans mon code (sscanf( ligne , "f %d%*[^ ]%d%*[^ ]%d" , &int1 , &int4, &int7 );) qui a l'air de marcher correctement. Je pense que ca suffit pour mon programme : ce n'est pas une entrée utilisateur qui est analysée mais une ligne dans un fichier au format Wavefront donc pas de risque d'erreur en principe. Merci pour vos réponses, bonne soirée.

  11. #11
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2020
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2020
    Messages : 13
    Par défaut
    J'ai parlé un peu vite... Ca ne marche pas dès que le "triplet" précédent n'a qu'un seul paramètre. Par exemple (f...1/2/5....2....3/3) donne (1,2,n'importe quoi) et (f...2....3...4) donne (2,n'importe quoi, n'importe quoi). Pourquoi cette fonciton sscanf est-elle si bizarre ?

  12. #12
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Quand tu écris (f...1/2/5....2....3/3) qu'y a-t-il effectivement à la place des ...? D'après ta description initiale ça serait juste une espace "f 1/2/5 2 3/3" et ça devrait marcher. Attention par exemple s'il y des tabulations à la place il faut adapter en écrivant "%*[^ \t]%d%*[^ \t]%d%*[^ \t]%d".

Discussions similaires

  1. Caractères spéciaux dans une string
    Par sebRD dans le forum C#
    Réponses: 20
    Dernier message: 28/06/2011, 01h49
  2. Réponses: 13
    Dernier message: 09/01/2008, 01h32
  3. Réponses: 6
    Dernier message: 24/07/2007, 12h56
  4. Récuperer des caractères Majuscules dans une chaine
    Par Loïc59 dans le forum Général VBA
    Réponses: 3
    Dernier message: 17/05/2007, 00h14
  5. Réponses: 4
    Dernier message: 07/01/2006, 18h36

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