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écupèrer un morceau d'une chaine par rapport à sa position dans la chaine


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 16
    Par défaut Récupèrer un morceau d'une chaine par rapport à sa position dans la chaine
    Bonjour.

    Avant toutes choses, sachez que je débute en C, ça peut être interessant à savoir

    Exemple illustrant mon problème :

    J'ai une chaîne de caractère type "aaaaaaabbbbbbbccdd" qui a toujours la meme longueur, mais ne contient pas tout le temps les mêmes caractères.
    On pourrait avoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char chaine = "bonjourcommentcava";
    Et j'aimerai récupérer dans une structure définie chaque élément de la chaine de caractère ; c'est à dire "bonjour", "comment", "ca", "va" dans une partie de la structure.

    Voilà un bout de code que j'ai commencé à écrire avant de rester bloqué sur ce probleme :

    Soit la structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct ligne
    {
      char a;
      char b;
      char c;
      char d;
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    strcpy(ligne.a, chaine(morceaudechaine)) ;
    strcpy(ligne.b, chaine(morceaudechaine)) ;
    strcpy(ligne.c, chaine(morceaudechaine)) ;
    strcpy(ligne.c, chaine(morceaudechaine)) ;
    où chaine(morceaudechaine)) doit en fait correspondre non pas à la chaine complète mais seulement au morceau de chaine correspondant à "bonjour", "comment", "ca", "va".
    De sorte que
    ligne.a soit égale à "boujour"
    ligne.b ******* à "comment"
    ...ainsi de suite.

    Comme je ne peux pas les récupèrer par rapport aux différents caractères de la chaine car ils ne seront pas toujours les mêmes, peut être faut il agir au niveau de leur position dans la chaine de caractère, en demandant de récupèré dans :
    ligne.a égale le morceau de la chaine qui va de la position 0 à 6
    ligne.b ************************************* 6 à 13
    ...ainsi de suite.

    Si quelqu'un connait une fonction standard qui effectue cette opération, je suis preneur...sinon s'il y a un autre moyen, je l'attends avec impatience.

    S'il faut plus de précision, je vous en apporterez volontiers.

    D'avance merci !

  2. #2
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    D'une manière ou d'une autre, il te faut trouver un moyen de définir où commence chaque partie dans la chaîne à découper. Je vois les possibilités suivantes:
    • Chaque partie de ta chaine a une longueur définie
    • Tu utilises un séparateur comme (virgule, espace (pour des mots), point (pour des phrases), caractère de tabulation, nouvelle ligne, motif spécifique) pour distinguer les différentes parties
    • Chaque partie commence par une lettre majuscule
    • etc.


    Sinon, difficile de savoir, à priori, comment découper "bonjourcommentcava".

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  3. #3
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 16
    Par défaut
    Citation Envoyé par mujigka
    • Chaque partie de ta chaine a une longueur définie
    Effectivement, chaque partie de la chaine a une longueur définie.
    Dans l'exemple, on a pour "boujour" 7 caractères qui lui sont attribué.
    Je me suis mal exprimé, mais quand j'ai décrit la chaine étant de type "aaaaaaabbbbbbbccdd" c'est ce que je voulais expliquer.
    Il y a 4 parties dans la chaine :
    aaaaaaa qui a une longueur de 7 caractères
    bbbbbbb qui a une longueur de 7 caractères
    cc qui a une longueur de 2 caractères
    dd qui a une longueur de 2 caractères
    On a pour chaque partie de la chaine une longueur définie qui ne varie pas.

    Soit dans l'exemple :
    7 caractères pour bonjour
    7 pour comment
    2 pour ca
    2 pour va

    Donc on peut a priori jouer sur la longueur de chaque partie de la chaine.
    Mais je ne vois pas comment m'y prendre.
    Car il n'y a pas de séparateur, ni de majuscule dans ma chaine de caractère.

    J'espère que vous pouvez m'aider à trouver la solution.

    Merci d'avance !

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    86
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 86
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int ret = 0;
    struct ligne_
    {
      char  a[7+1];/*+1=le caractere fin de chaine*/
      char  b[7+1];
      char  c[2+1];
      char  d[2+1];
    }ligne;
     
    char * str = "aaaaaaabbbbbbbccdd";
     
    ret = sscanf(str,"%7s%7s%2s%2s",ligne.a,ligne.b,ligne.c,ligne.d);
    if(ret !=4)return -1;

  5. #5
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 16
    Par défaut
    Ok, merci scriptoff.

    Je vais essayer ça.
    Par contre, pourrais je avoir une explication du code ?

    • Et si (oui j'en rajoute un peu ) les deux derniers "caractères" étaient des rééls, est-ce que sscanf() peut les lire aussi ?
    • Et si je veux récupéré tous les éléments de la chaines sauf ceux en position "c".
      C'est à dire, au lieu de "aaaaaaabbbbbbbccdd", "aaaaaaabbbbbbbdd".
      Soit "boujour", "comment", "va".



    J'essai ce qu'on me propose en l'adaptant à mon code et je vous dis si cela a bien fonctionné.

    Merci encore !

  6. #6
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 16
    Par défaut
    J'effectue un double post (désolé ) pour dire que l'idée du sscanf est effectivement une bonne solution pour résoudre mon problème.
    Je vous remercie de m'avoir fournis cette solution.

    En revanche, il se trouve qu'il me serait utile de faire évoluer ma première question vers celle que j'ai posé ci avant :

    Les deux derniers "caractères" étaient des rééls, est-ce que sscanf() peut les lire aussi ?
    Je veux récupéré tous les éléments de la chaines sauf ceux en position "c".
    C'est à dire, au lieu de "aaaaaaabbbbbbbccdd", "aaaaaaabbbbbbbdd".
    Soit "boujour", "comment", "va".

    Réémettons les hypothèses de départs plus adaptés à ces questions :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct ligne
    {
      char a;
      char b;
      /*char c; --> on supprime cette élément de la structure*/
      int d; /* on a un int et non plus un char */
    };
     
    char * str = "aaaaaaabbbbbbbccdd";
    on veur récupéré dans la structure juste les chaine :
    "aaaaaaa" dans ligne.a
    "bbbbbbb" dans ligne.b
    "dd" dans ligne.d

    Comment écrire le sscanf pour obtenir ce résultat ?

    J'espère que mes questions sont assez clairs et que vous pourrez fournir une aide bénéfique à mon code

    Merci d'avance

  7. #7
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par MJfox
    Effectivement, chaque partie de la chaine a une longueur définie.
    Dans l'exemple, on a pour "boujour" 7 caractères qui lui sont attribué.
    Je me suis mal exprimé, mais quand j'ai décrit la chaine étant de type "aaaaaaabbbbbbbccdd" c'est ce que je voulais expliquer.
    Il y a 4 parties dans la chaine :
    aaaaaaa qui a une longueur de 7 caractères
    bbbbbbb qui a une longueur de 7 caractères
    cc qui a une longueur de 2 caractères
    dd qui a une longueur de 2 caractères
    On a pour chaque partie de la chaine une longueur définie qui ne varie pas.

    Soit dans l'exemple :
    7 caractères pour bonjour
    7 pour comment
    2 pour ca
    2 pour va

    Donc on peut a priori jouer sur la longueur de chaque partie de la chaine.
    Mais je ne vois pas comment m'y prendre.
    Car il n'y a pas de séparateur, ni de majuscule dans ma chaine de caractère.

    J'espère que vous pouvez m'aider à trouver la solution.
    Une utilisation intelligente de strncat() permet de copier une sous-chaine définie par un offset et une longueur. Bien lire la doc.

    Evidemment, les tableaux de destination doivent être d'une taille suffisante (<= à la chaine originale, bien sûr...)

    Se rappeler qu'une chaine est terminée par un 0...

  8. #8
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 16
    Par défaut
    Bonjour.

    Vous voulez dire que je pourrais écrire quelque chose de la sorte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *strncat (ligne.a, str, 7)
    Mais strncat ne copie que les n premiers caractères de src a la fin de dest.
    Comment récupérer les "bbbbbbb" de str dans ligna.b ? les "dd" dans ligne.d.
    Avec cette fonction je ne peux récupérer que la chaine pour les "aaaaaaa".

    A moins que l'on supprime la même chose à la chaine str à chaque fois que l'on copie dans la structure ?
    Mais on perd la chaine de départ, et cela peut être assez contraignant.


    Etayons un peu les hypothèses pour donner un peu plus de matières à ma question, car apparement, je ne suis pas assez clair dans mes explications.

    Imaginons :

    J'extrait d'un fichier une ligne de 100 caractères de ce fichier.
    Je stock cette ligne dans une variable "str".
    Dans cette ligne/variable, une valeur A de 7 caractères que l'on trouve en 25ème position et une de 2 caractères en 46ème m'interesse.
    La valeur A sera un char.
    la valeur B sera un int.
    Comment récupérer ces deux valeurs dans une structure (type lastructure comme définit au dessus) ?

    Peut être l'exemple présenté comme ca explique mieux ce que je recherche ?


    PS :
    Pourquoi n'existe t'il pas une fonction :
    Recup(str,25-32,ligne.a)
    Recup(str, 46-48, ligne.d)

    Cela serait tellement plus simple...

  9. #9
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par MJfox
    Mais strncat ne copie que les n premiers caractères de src a la fin de dest.
    Comment récupérer les "bbbbbbb" de str dans ligna.b ? les "dd" dans ligne.d.
    Avec cette fonction je ne peux récupérer que la chaine pour les "aaaaaaa".
    Tu te deplaces dans la chaine : c'est le moment de comprendre ce qu'est un pointeur.
    Tu as
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char chaine[] = "bonjourcommentcava";
    chaine + 7 te place sur le c de comment.

  10. #10
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    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
    /**
     * Récupère une sous-chaîne de n caractères depuis s_src[debut] et la copie
     * dans s_dest.
     *
     * @param s_dest tampon de destination dans lequel sera copié la chaine
     * @param s_src chaîne de caractères contenant la sous-chaine à copier
     * @param debut indice indiquant le début de la sous-chaîne à copier
     * @param n longueur de la sous chaine à copier
     * 
     * @pre debut doit être un entier compris entre 0 et strlen(s_src) - 1
     * @pre n doit être inférieur strictement à la taille de s_dest 
     */
    void Recup(char *s_dest, char const *s_src, int debut, int n)
    {
        strncat(s_dest, s_src + debut, longueur);
    }
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 24/02/2011, 13h22
  2. Réponses: 3
    Dernier message: 01/06/2009, 18h21
  3. Réponses: 8
    Dernier message: 15/11/2008, 23h14
  4. Réponses: 5
    Dernier message: 29/08/2008, 18h01
  5. Réponses: 7
    Dernier message: 08/03/2007, 16h42

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