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 :

Transformer une chaine de caractères


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    384
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 384
    Points : 52
    Points
    52
    Par défaut Transformer une chaine de caractères
    Bonjour

    Je reçois dans une variable des caractères issus d'un port série, ils arrivent comme ceci :

    <CR><LF>HELLO<CR><LF>

    Je voudrai au final, ne récupérer que le contenu qui m'intéresse c'est à dire juste le mot "Hello" et mettre à la fin du mot reçu le caractère de fin "\0"

    Mon but est de supprimer tout les caractères /r/n de début et fin de chaine.

    J'ai fait ceci, mais ça ne fonctionne pas convenablement, pourriez vous m'aider svp ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    unsigned char buffer_reception[80];
     
    ...
     
    for(i=2;i<80;i++)		// On ne regarde qu'après la 3eme position de la séquence recue.
    if (buffer_reception[i]== '\n')	// Recherche du dernier caractère '\r' 
    {
    buffer_reception[i] = '\0';  // '/r' trouvé ? on le remplace par '\0'		
     
    for (i=2; buffer_reception[i] != '\0'; ++i)  // Ré-écriture de la chaine en décalant -2 à gauche pour supprimer les premiers caractères /r/n
    buffer_reception[i-2] = buffer_reception[i];
    }
    Je vous remercie de votre aide,

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Une question du même style a déjà été posée hier : http://www.developpez.net/forums/d10...ctere-fichier/

  3. #3
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    384
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 384
    Points : 52
    Points
    52
    Par défaut
    Mon problème est que la taille de ce qui est reçu n'est pas connu à l'avance :
    la seule constante, c'est que chaque chaine reçu commence et finie par /r/n

    J'ai pensé utiliser strstr pour remplacer chaque /r/n par '\0'

    en faisant ainsi, je vais me retrouver avec ceci :

    \0CHAINE RECUE\0

    Le premier '\0' va pose problème pour exploiter le contenu de cette chaine.

    Que me conseilleriez vous , faut il tout décaler d'un caractère vers la gauche ?

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 064
    Points
    219 064
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Je me demande quoi vous voulez avoir un '\0' (ou autre) au début.
    Juste un à la fin, indique la fin du message
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    384
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 384
    Points : 52
    Points
    52
    Par défaut
    Bonjour,

    Si je remplace chaque /r/n par un caractère de fin, je vais forcement me retrouver avec deux \0 en début de chaine.

    Je voudrai éviter cela justement.
    Est ce que la meilleure méthode consiste à tout déplacer : les 80 caractères, 2 rangs vers la gauche pour les 2 premiers \0 ?

    Je pense que tout déplacer prend du temps, je ne suis pas certain que ce soit la meilleure solution ...

    Je vous remercie de votre aide,

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Y a plein de façons de faire. Maintenant, cela dépend à quoi va servir cette chaine, comment elle sera utilisée, sur quoi tu travailles (PC, µc -contrainte d'optimiser taille code/vitesse-, etc), etc. On ne connait pas ce genre d'info, on ne peut pas t'aiguiller vers telle ou telle voie.

    Parmi les méthodes :

    * Soit copier dans un autre buffer, en copiant tout ce qui se trouve entre les deux \r\n.

    * Soit remplacer le dernier \r\n par \0 et utiliser un pointeur qui pointera à l'adresse "buffer_reception+2".

    * Soit tout décaler de deux caractères à gauche et remplacer le dernier \r\n par \0.

    * ...

    Telle méthode peut convenir comme elle peut ne pas convenir, il n'y a pas de solution universelle. C'est l'art de la programmation : coder de telle ou telle manière en fonction du contexte, des contraintes, etc.

  7. #7
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    384
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 384
    Points : 52
    Points
    52
    Par défaut
    Ce code sera utilisé dans un microcontroleur Pic ( C embarqué ) dans une fonction d'interruption, dans donc mon cas le temps de traitement doit être le plus court possible.

    Je pense que passer par un buffer intermédiaire risque s'allonger le temps de traitement, n'est-ce pas ?

    Pourrais tu me montrer la méthode avec des
    pointeurs ?

  8. #8
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    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 : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,
    Citation Envoyé par lcoulon Voir le message
    Ce code sera utilisé dans un microcontroleur Pic ( C embarqué ) dans une fonction d'interruption
    A proscrire complètement. Ton interruption devrait se contenter de mettre les octets reçu dans un tampon circulaire. Tout le reste devrait être fait à l'extérieur. A mon sens, un driver uart devrait contenir (hormis la configuration et le remplissage par interruption) deux fonctions: une qui renvoie le nombre d'octets en attente dans le tampon et une qui enlève et renvoie le plus ancien octet reçu du tampon. Plus la gestion des erreurs, 'buffer full et 'timeout'.

    Pour le reste de ton problème, donc en dehors de l'interruption, il faudrait créer un buffer suffisant pour extraire une à une les chaines du tampon, remplacer les '/r/n' par \0. Là, tu as ta chaine dans un buffer fixe, libre à toi après de la "monter en mémoire" par un malloc/strcpy ou une fonction combinant les 2.

    A+

    Pfeuh

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Ce code sera utilisé dans un microcontroleur Pic ( C embarqué ) dans une fonction d'interruption, dans donc mon cas le temps de traitement doit être le plus court possible.

    Je pense que passer par un buffer intermédiaire risque s'allonger le temps de traitement, n'est-ce pas ?

    Pourrais tu me montrer la méthode avec des
    pointeurs ?
    Mais tout dépend justement ce que tu vas faire avec ce buffer... Est-ce que son contenu est susceptible de changer ? Faut-il conserver son contenu ? etc... Tu ne donnes pas beaucoup de précision.

    Ma méthode avec les pointeurs, c'est une solution sale, mais qui évite de copier ou déplacer XX caractères, et qui économise du temps d'exécution. Par contre, si c'est un buffer où les données sont susceptibles d'être modifiées, n'utilise surtout pas cette méthode.

    Avant toute chose, je précise que je n'ai jamais programmé pour µc, ma solution ne convient donc peut-être pas du tout pour ce cas. Je ne sais pas comment sont gérées les interruptions, ni quels effets ma méthode peut avoir dessus (peut-être néfastes ?).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    char buffer[80]; /* format : \r\nchaine caracteres\r\n\0 */
    char * chaine = buffer + 2;
    char adresse_crlf = strstr ( chaine , "\r\n"); /* "strstr" ou un code de ton cru qui fait la même chose (pour des question d'optimisation) */
    if ( adresse_crlf != NULL ) *adresse_crlf = '\0';
     
    /* "chaine" pointe vers : "chaine caracteres\0" */
     
    ...
    J'insiste bien : c'est pas propre et il n'y a aucune sécurité. Après, c'est comme tout : si on sait exactement ce qu'on fait et qu'on sait en gérer les conséquences éventuelles, faut voir...

    Mais concernant les PIC (et les µc en général), j'insiste bien : je ne suis pas connaisseur. Prends mon message avec des pincettes.

  10. #10
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    384
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 384
    Points : 52
    Points
    52
    Par défaut
    En fait, ce buffer de reception : buffer[80] va effectivement changer de contenu à chaque fois qu'une trame série se présente, cela se présentera environ 1 à 2 fois par seconde.

    Donc, oui ce buffer va changer de contenu assez souvent,

    Par contre j'envisage de garder le contenu des 3 dernieres receptions reçues afin de les afficher, sans les /r/n.

    Il y aura donc 3 autres buffers destinés à l'affichage des 3 dernieres données reçues.



    Pour que vous ayez une vue d'ensemble, voici le but final de ce que je veux obtenir :

    On reçoit dans buffer[80] = "/r/nHELLO/r/n";

    on transformer cela en : "HELLO"
    on recopie le resultat dans buffer_affichage1

    quelques millisecondes plus tard , on reçoit dans buffer[80] = "/r/n2eme reception/r/n";
    on transformer cela en : "2eme reception"
    on recopie le resultat dans buffer_affichage2

    quelques millisecondes plus tard , on reçoit dans buffer[80] = "/r/n3eme reception/r/n";
    on transformer cela en : "3eme reception"
    on recopie le resultat dans buffer_affichage3

    quelques millisecondes plus tard , on reçoit dans buffer[80] = "/r/n4eme reception/r/n";
    on transformer cela en : "4eme reception"
    on recopie le resultat dans buffer_affichage1

    Au bout de la 4eme reception : on écrase buffer_affichage1

    Donc je ne sais pas quel serait le meilleur principe pour supprimer rapidement les /r/n de buffer.

Discussions similaires

  1. Transformer une chaine de caractère
    Par Invité dans le forum Django
    Réponses: 3
    Dernier message: 06/03/2009, 09h57
  2. Réponses: 11
    Dernier message: 04/11/2007, 21h32
  3. Réponses: 3
    Dernier message: 12/06/2006, 11h18
  4. Réponses: 2
    Dernier message: 03/10/2005, 16h23
  5. Réponses: 2
    Dernier message: 14/01/2005, 15h40

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