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 :

traitement sur une chaîne, votre aide souhaitée !


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Mars 2020
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs

    Informations forums :
    Inscription : Mars 2020
    Messages : 62
    Points : 38
    Points
    38
    Par défaut traitement sur une chaîne, votre aide souhaitée !
    Bonjour à tous .

    Bon ben ces temps-ci, à part se prendre la tête avec nos petits programmes que faire d'autre ?

    Je suis nul en C, je sollicite votre aide pour ce petit programme dont je souhaite qu'il puisse extraire les 6
    derniers caractères d'une adresse MAC sans les ':'. J'ai tenté des sscanf et autres fonctions de traitement des
    chaines mais sans succès. Le programme suivant affiche pour le moment:

    08:60:6e:8c:2a:c7
    08606e8c2ac7

    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
     
    int main()
    {
        FILE* fichier = NULL;
        char chaine[100] = "";
        fichier = fopen("/sys/class/net/enp2s0/address", "r");
     
            if (fichier != NULL)
                {
                        while (fgets(chaine, 100, fichier) != NULL)
                        {
               printf("%s", chaine);
     
               char *p = strtok(chaine, ":");
                          while(p != NULL)
                          {
                                printf("%s", p);
                                p = strtok(NULL, ":");
                            }
                    }
     
                                fclose(fichier);
                                            }
     
    }

  2. #2
    Membre éclairé
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Septembre 2015
    Messages
    204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Septembre 2015
    Messages : 204
    Points : 839
    Points
    839
    Par défaut
    bonjour

    donc tu souhaites obtenir "8c2ac7" ?

    - soit tu commences à traiter ta chaine à 8c :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char *c;
    c = chaine;
    c += 9; // pour sauter 08:60:6e:
    // ensuite tu fais tes traitements sur c
    - soit à la fin de ton traitement, tu affiches les 6 derniers
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char *c = ta_chaine_resultat;   // car chaine est modifiée par strtok; donc tu dois construire ta_chaine_resultat
    while (*c) c++;
    c -= 6; // récupérer les 6 derniers caractères
    // tu affiches c

    par contre, pour le pseudo code donné ci-dessus, il faut bien tester les longueurs de chaine (= je ne vérifie pas la structure de ton adresse mac, je suppose qu'elle est correcte)

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Avec ton format fixe le sscanf est sans doute le plus simple.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const char* mac = "08:60:6e:8c:2a:c7";
    char a[3], b[3], c[3], d[3], e[3], f[3];
    sscanf(mac, "%2s:%2s:%2s:%2s:%2s:%2s", a, b, c, d, e, f);
    printf("%s%s%s%s%s%s", a, b, c, d, e, f);
    Tu peux aussi faire un remove des : dans la chaîne d'origine.
    Un truc du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void remove_char(char* src, char toRemove)
    {
      const int total_length = strlen(src);
      while (char* found = strchr(src, toRemove))
      {
        const int chars_before = found - src;
        const int length_after_char = total_length - chars_before;
        memmove(found, found + 1, length_after_char + 1); // Ajoute 1 pour garder le \0
      }
    }
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Mars 2020
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs

    Informations forums :
    Inscription : Mars 2020
    Messages : 62
    Points : 38
    Points
    38
    Par défaut
    Bonjour,

    Oui c'est exactement cela, du coup j'obtiens:
    08:60:6e:8c:2a:c7
    8c:2a:c7
    8c2ac7

    avec =>
    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
     
     
    int main()
    {
        FILE* fichier = NULL;
        char chaine[100] = "";
        char souschaine[100];
        fichier = fopen("/sys/class/net/enp2s0/address", "r");
        if (fichier != NULL)
                {
                        while (fgets(chaine, 100, fichier) != NULL)
                        {
               printf("%s", chaine );
                                char *c;
                                c = chaine;
                                c += 9;
                                printf("%s", c);
     
               char *p = strtok(c, ":");
                          while(p != NULL)
                          {
                                printf("%s", p);
                                p = strtok(NULL, ":");
                            }
                    }
     
                                fclose(fichier);
                                            }
     
    }
    J'aimerai associer ce résultat à une variable pour la traiter plus loin dans le programme, j'utilise sprintf ?

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Mars 2020
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs

    Informations forums :
    Inscription : Mars 2020
    Messages : 62
    Points : 38
    Points
    38
    Par défaut
    Merci pour ta réponse, cela me donne le code suivant qui effectivement me permet de stocker
    les valeurs dans les variables a, b, c .....
    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
     
     
    if (fichier != NULL)
                {
                        while (fgets(chaine, 100, fichier) != NULL)
                        {
                                printf("%s", chaine );
     
                                char a[3], b[3], c[3], d[3], e[3], f[3];
                                sscanf(chaine, "%2s:%2s:%2s:%2s:%2s:%2s", a, b, c, d, e, f);
                                printf("%s %s %s", d, e, f);
     
                    }
     
                                fclose(fichier);
                                            }

    Citation Envoyé par Bousk Voir le message
    Avec ton format fixe le sscanf est sans doute le plus simple.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const char* mac = "08:60:6e:8c:2a:c7";
    char a[3], b[3], c[3], d[3], e[3], f[3];
    sscanf(mac, "%2s:%2s:%2s:%2s:%2s:%2s", a, b, c, d, e, f);
    printf("%s%s%s%s%s%s", a, b, c, d, e, f);
    Tu peux aussi faire un remove des : dans la chaîne d'origine.
    Un truc du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void remove_char(char* src, char toRemove)
    {
      const int total_length = strlen(src);
      while (char* found = strchr(src, toRemove))
      {
        const int chars_before = found - src;
        const int length_after_char = total_length - chars_before;
        memmove(found, found + 1, length_after_char + 1); // Ajoute 1 pour garder le \0
      }
    }

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Mars 2020
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs

    Informations forums :
    Inscription : Mars 2020
    Messages : 62
    Points : 38
    Points
    38
    Par défaut variables statiques ?
    re bonjour,

    Afin de pouvoir utiliser les variables stockées par sscanf() dans une autre fonction je les ai déclarées
    statiques en début de programme:

    static char a[3], b[3], c[3], d[3], e[3], f[3];

    Est-ce une abérration pour vous ou faut-il utiliser des pointeurs ?

    Merci pour votre avis.

  7. #7
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Bonjour.

    Par principe, mais rien n'est interdit, il faut éviter les déclarations en global. C'est à dire en dehors de toute fonction.

    Tu as plusieurs solutions pour résoudre cette difficulté:
    • transmettre à toutes les fonctions les adresses des variables déclarées,
    • regrouper tout ce petit monde dans une structure, déclarer une variable du type de la structure et transmette son adresse aux différentes fonctions,
    • déclarer un tableau char de taille 9 et transmettre son adresse aux différentes fonctions. (il suffit d'indenter un index pour lire les différentes données).

    Il y a sûrement d'autres possibilités.

    [Edit]

    Pour la troisième possibilité voici comment tu peux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     const char* mac = "08:60:6e:8c:2a:c7";
      printf ("mac : %s\n", mac);
     
      char a[3], b[3], c[3], d[3], e[3], f[3];
      char code [10];
      sscanf(mac, "%2s:%2s:%2s:%2s:%2s:%2s", a, b, c, d, e, f);
      printf ("d, e, f : %s, %s, %s\n", d, e, f);
     
      strcat(code, d);
      strcat(code, e);
      strcat(code, f);
      printf("%s\n", code);
    Tu récupères dans code[] les données. Tu peux transmettre ce tableau aux fonctions de traitement. Ainsi, une fois la fonction dans laquelle tu l'as déclaré se termine, il sera aussi détruit. Pas de perte mémoire et un code plus robuste. Les fonctions ne modifient que les données qui leurs sont transmises.

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Mars 2020
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs

    Informations forums :
    Inscription : Mars 2020
    Messages : 62
    Points : 38
    Points
    38
    Par défaut
    Super, ça avance, merci beaucoup à vous tous pour votre aide.

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par netlink1987 Voir le message
    Afin de pouvoir utiliser les variables stockées par sscanf() dans une autre fonction je les ai déclarées
    statiques en début de programme:

    static char a[3], b[3], c[3], d[3], e[3], f[3];

    Est-ce une abérration pour vous ou faut-il utiliser des pointeurs ?
    Un pointeur n'est qu'un outil. Si tu n'en as pas besoin alors il faut pas te forcer. D'autant plus qu'utiliser un pointeur dans un terme aussi vague ça ne veut rien dire (tout comme tu aurais dit "faut-il utiliser l'addition" ça aurait été pareil).
    Car réfléchissons bien: quand on utilise un pointeur (ex char *pt) on est obligé à un moment ou à un autre d'écrire pt=adresse valide (sauf si le pointeur est un paramètre de fonction mais dans ce cas là la copie est faite implicitement lors de l'appel de la fonction). Donc quoi mettre dans pt ?
    • une allocation => char *pt; pt=malloc(3 * sizeof(char)). Ok mais c'est idiot d'utiliser un truc aussi lourd qu'un malloc là où on peut faire la même chose en plus simplement avec un tableau
    • un pointeur qui pointerait alors vers une variable connue (et très probablement celle d'un tableau) => char a[3]; char *pt=a. Ok, mais alors quel est son avantage par rapport à "a" ?

    La seule solution pour laquelle des pointeurs "pourraient" être utilisés, c'est pour les placer au point de départ de chaque partie de l'adresse. Ex pour 08:60:6e:8c:2a:c7, alors un pointeur placé sur la partie de la chaine contenant "08", un autre placé sur le "60" et etc. Mais ça t'obligerait toutefois à remplacer les ":" par des '\0' pour que chaque chaine pointée s'arrête à la fin de sa propre partie. Faisable mais ça implique une modification de la donnée initiale et il peut arriver que ça te desserve plus tard (à réfléchir donc).

    En revanche, pour stocker 6 valeurs de 3 caractères, perso je serais passé par un tableau 2D (char mac[6][3]). Ou alors, si on veut pouvoir expliciter les différentes valeurs tout en pouvant les manipuler ensembles, par une structure (typedef struct {char a[3]; char b[3]; char c[3]; char d[3]; char e[3]; char f[3];} t_mac;). Ce qui permet alors de ne plus avoir besoin de les mettre en global (car en pouvant les manipuler d'un coup, tu peux alors les passer d'un coup à tes différentes fonctions qui en auront besoin). Elle est là l'aberration: utiliser 6 variables indépendantes pour stocker un groupe d'éléments qui vont ensembles.
    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]

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Mars 2020
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs

    Informations forums :
    Inscription : Mars 2020
    Messages : 62
    Points : 38
    Points
    38
    Par défaut
    Bonjour,

    D'autant que l'on ne peut pas dire que je sois à l'aise avec le C ....

    Si je peux faire simple, je fais simple !

    Merci pour ces explications.

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Il faut sans doute initialiser les tableaux avec un \0 final sinon je suis pas sûr que sscanf le rajoute.

    Si tu veux faire simple c'est Python qu'il faut utiliser pour ce truc, pas C, surtout quand on connait pas/mal.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  12. #12
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bousk Voir le message
    sinon je suis pas sûr que sscanf le rajoute.
    Si, c'est une assurance. Toutes les fonctions de création de chaines rajoutent le '\0' à la fin de la chaine créée. A 2 exceptions près avec strncpy() et strncat() qui remplissent le tableau de destination avec au plus "n" caractères et si "n" est atteint avant la fin de la chaine à copier, ne rajoutent alors pas le \0'.
    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. [MySQL] Traitement d'une chaîne avant insertion
    Par yann_p dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 18/08/2006, 15h20
  2. recherche sur une chaîne de caractères
    Par bogsy15 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 17/07/2006, 12h01
  3. Tri sur une chaîne de caractères contenant des nombres
    Par arnaud_verlaine dans le forum Langage SQL
    Réponses: 2
    Dernier message: 23/05/2006, 11h52
  4. Requête sur une chaîne de caractères
    Par Hakunamatata dans le forum Langage SQL
    Réponses: 9
    Dernier message: 02/04/2006, 18h27
  5. Réponses: 2
    Dernier message: 02/03/2006, 17h38

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