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 :

Buffer de caracteres et pointeur.


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Par défaut Buffer de caracteres et pointeur.
    Bonjour je dois utiliser un morceau de code du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    /*...*/
    #define MAX 1025
    char buffer[MAX];
    char* buffer_ptr;
    /*...*/
    J'imagine que l esprit de ces déclarations est d utiliser buffer_ptr pour pointer sur le caractere courant dans le tableau buffer pour faire un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    /* ....Quelque part 'avant', dans main par exemple */
    buffer_ptr = &(buffer[0]);
    int AppendBuffer (const char c)
    {
        *(buffer_ptr++)=c; 
     /* J ai bien conscience que je ne gere pas du tout la fin de buffer
      * C est justement autour de ca que porte ma question
      */
      return 1;
     
    }
    mais je ne vois pas vraiment l intérêt de procéder de la sorte par rapport à l'utilisation d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int buffer_index = 0;
    en lieu et place du buffer_ptr et une utilisation du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    /* ....Quelque part 'avant', dans main par exemple */
    buffer_ptr = &(buffer[0]);
    int AppendBuffer (const char c)
    {
        if (buffer_index < MAX) { buffer[buffer_index++]=c; return 1;}
        else {return 0;}
    }
    J'ai l'impression que l'utilisation de buffer_ptr ne me permet pas a elle seule de gérer un eventuel depassement de la taille du buffer et que de toutes facons, je suis obligé de définir et maintenir un buffer_index.
    En plus clair (si ce n'est pas deja la cas) puis je ajouter un caractere a mon buffer en prenant en compte la taille de ce dernier et sans utiliser d'index numérique ?

    J'ai la (très) désagréable impression de passer à côté d'un truc important

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 309
    Billets dans le blog
    5
    Par défaut
    Je dirai que tu ne peux effectivement pas maîtriser le dépassement. Soit tu utilises un index (ce que tu proposes), soit tu fixes une valeur du dernier caractère du tableau lors de son initialisation.

    À chaque inscription dans le buffer il te suffit de vérifier avant si le dit caractère n'est pas présent à l'emplacement actuel. Si oui alors tu as atteint la fin du buffer.

    Ce principe est utilisé par les nombreuses fonctions type printf(); pour connaître la longueur des buffers transmis. Le caractère spécial est le "\0". Ceci sous-entend que ton tableau devra avoir la taille du texte+1 pour le caractère de fin.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 833
    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 833
    Billets dans le blog
    1
    Par défaut
    Salut

    L'utilisation d'un pointeur à la place d'un index n'a qu'une seule utilité: la rapidité.
    En effet, dans l'écriture suivante...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char chaine[]="Hello";
    size_t i;
     
    for (i=0; chaine[i] != '\0'; i++)
        printf("%c", chaine[i]);
    ...chaque fois que tu t'adresses à l'élément [i] (ici 2 fois), le C recalcule le déplacement de i par rapport au début de tableau. Une fois cet offset calculé, il va alors chercher le contenu de la case.

    C'est pour éviter ce recalcul qu'on peut passer par un pointeur
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char chaine[]="Hello";
    char *pt;
     
    for (pt=chaine  /* Plus rapide que d'écrire &chaine[0] */; *pt != '\0'; pt++)
        printf("%c", *pt);
    Dans cet exemple, pt est un pointeur qui s'incrémente et qui conserve, entre deux itérations, sa valeur. Il n'y a donc pas de "recalcul". Ensuite l'opération "*pt" (aller chercher le contenu de la case) reste la même que tout à l'heure.

    Toutefois, à ce niveau là, le gain est minime. Parce que calculer un offset sur des char (octets) va super vite. Là où ça va vraiment jouer un rôle, ce sera avec des tableaux de structures...

    Code c : 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
    typedef struct {
        char nom[20 + 1];
        char prenom[20 + 1];
        unsigned short age;
    } t_personne
     
    t_personne tabP[]={
        {".....", "......", x},
        {".....", "......", x},
        {".....", "......", x},
        {"", "", 0},
    };
     
    size_t i;
    t_personne *pt;
     
    for (i=0; tapP[i].age != 0; i++)
        printf("Nom: %s, prénom: %s, age; %hu\n", tapP[i].nom, tabP[i].prenom, tabP[i].age);
     
    for (pt=tapP; pt->age != 0; pt++)
        printf("Nom: %s, prénom: %s, age; %hu\n", pt->nom, pt->prenom, pt->age);
    La première boucle prendra un temps phénoménal comparé à la seconde car déjà l'index [i] est demandé 4 fois et en plus calculer un offset sur un tableau de structures avec une taille anarchique (ici 44 octets) est super compliqué. Bon dans la réalité c'est devenu moins vrai depuis qu'il y a des optimiseurs de codes qui rajoutent des octets bidons dans la structure pour les caler sur des mots machines (ce qui accélère le calcul) mais c'est pour te montrer l'idée (et il reste quand même le fait que [i] est demandé 4 fois).
    Dans la seconde boucle, magie de l'arithmétique des pointeurs, pt est toujours positionné sur le bon élément à afficher. Ne reste qu'a déréférencer les membres (avec l'opérateur flèche) mais cette opération était aussi faite dans la première boucle (avec l'opérateur point)

    Citation Envoyé par BaygonV Voir le message
    J'ai l'impression que l'utilisation de buffer_ptr ne me permet pas a elle seule de gérer un eventuel depassement de la taille du buffer et que de toutes facons, je suis obligé de définir et maintenir un buffer_index.
    Pas forcément si tu utilises un drapeau de fin. C'est le rôle du '\0' dans une chaine de caractères et c'est ce que j'ai fait en mettant un élément supplémentaire avec age=0 dans mon tabP...
    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]

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Par défaut
    Oui j ai bien pensé a utiliser un drapeau, et en l occurence j ai bien pensé au caractere nul (les differents tutos que j ai parcourus ont l air clairs sur ce point).
    Mais ca veut dire que je dois donc faire attention à ce que ce drapeau ne soit present qu'a la fin du buffer (ou da la chaine qu il est censé contenir si elle est plus petite...)
    Et que donc a chaque fois que je vide le buffer je dois en quelques sorte le reinitialiser (ou l initialiser une fois au debut puis faire gaffe de virer le caractere nul qui risque d'apparaitre lorsqu il aura contenu une chaine plus petite)...
    (desolé je pense tout haut)
    Merci.

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 309
    Billets dans le blog
    5
    Par défaut
    Ben oui. Rien n'est parfait en ce bas monde

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Par défaut
    M'en parle pas !
    Au passage, et histoire de tenter de progresser plus vite, je vais tenter de donner des reponses aux questions qui me paraissent de mon niveau ici, est ce que je risque un ban si je specifie clairement que ma reponse est a prendre avec précaution (comme je l ai fait sur ce fil) ?

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 309
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par BaygonV Voir le message
    M'en parle pas !
    Au passage, et histoire de tenter de progresser plus vite, je vais tenter de donner des reponses aux questions qui me paraissent de mon niveau ici, est ce que je risque un ban si je specifie clairement que ma reponse est a prendre avec précaution (comme je l ai fait sur ce fil) ?
    Vouloir répondre à un post t'encourage à la rigueur. Bon maintenant tu ne tombes pas forcément juste à tous les coups (moi le premier ). Mais n'hésite pas à le faire.

  8. #8
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par BaygonV Voir le message
    Au passage, et histoire de tenter de progresser plus vite, je vais tenter de donner des reponses aux questions qui me paraissent de mon niveau ici, est ce que je risque un ban si je specifie clairement que ma reponse est a prendre avec précaution (comme je l ai fait sur ce fil) ?
    Tu ne risques pas de ban directement, tout simplement parce que d'abord tu passeras par la case avertissement.


    Plus sérieusement, nous encourageons totalement les gens à répondre aux autres. Ca aide à progresser, ça crée de l'activité sur le forum. La seule contrainte, comme l'a dit gerald3d, c'est que ta réponse doit être constructive et surtout ne doit pas être (totalement) fausse. Cette contrainte s'applique de toute façon quelque soit l'expérience de la personne qui répond.

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 833
    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 833
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par BaygonV Voir le message
    Mais ca veut dire que je dois donc faire attention à ce que ce drapeau ne soit present qu'a la fin du buffer (ou da la chaine qu il est censé contenir si elle est plus petite...)
    C'est encore plus basique que ça: c'est la présence de ce drapeau qui symbolise la fin logique de ton ensemble...

    Citation Envoyé par BaygonV Voir le message
    Et que donc a chaque fois que je vide le buffer je dois en quelques sorte le reinitialiser (ou l initialiser une fois au debut puis faire gaffe de virer le caractere nul qui risque d'apparaitre lorsqu il aura contenu une chaine plus petite)...
    Pas besoin de spécialement faire gaffe. Te suffit de mettre systématiquement ce flag à la fin de toute écriture sans te préoccuper des écritures précédentes. Si la nouvelle écriture prend plus de place que l'ancienne, alors le flag précédent sera automatiquement écrasé. Et si la nouvelle écriture prend moins de place alors il y aura deux flags mais seul le premier trouvé (qui sera en même temps le dernier a avoir été écrit) sera pris en compte...

    Citation Envoyé par BaygonV Voir le message
    M'en parle pas !
    Au passage, et histoire de tenter de progresser plus vite, je vais tenter de donner des reponses aux questions qui me paraissent de mon niveau ici, est ce que je risque un ban si je specifie clairement que ma reponse est a prendre avec précaution (comme je l ai fait sur ce fil) ?
    Tu ne risqueras jamais un ban pour avoir tenté d'aider quelqu'un en fonction de tes connaissances. Au pire tu risques une remarque si tu dis une connerie...
    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. Buffer de caracteres dans un fichier flex (analyse lexicale)
    Par BaygonV dans le forum Générateurs de compilateur
    Réponses: 2
    Dernier message: 03/02/2014, 16h56
  2. tableau de chaine de caractere avec pointeur
    Par Oussama1 dans le forum C++
    Réponses: 7
    Dernier message: 15/12/2008, 13h12
  3. Les caractères et pointeurs
    Par ajsd0208 dans le forum C
    Réponses: 5
    Dernier message: 07/08/2006, 12h56
  4. Incrémenter un pointeur sur un buffer de uchar
    Par Flo. dans le forum x86 32-bits / 64-bits
    Réponses: 6
    Dernier message: 12/12/2005, 08h38
  5. Réponses: 3
    Dernier message: 19/12/2004, 14h30

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