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 :

Position d'un caractère


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7
    Par défaut Position d'un caractère
    Bjour tous,

    j'ai un souci avec une fonction type strpos de php que j'ai faite en C. Elle doit retourner la position d'un caractère dans une chaine. La voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int substrlen (char *chaine, char *car)
    {
     return (strstr (chaine, car) - chaine);
    }
    Je dois en fait retrouver la position d'un retour chariot dans une chaine pour modifier le caractère (en fait, un header http que je dois couper en lignes). Jusque là, pas de problème, ma fonction me retrouve bien la position de mon caractère. Sauf que, quand j'essaye de modifier mon caractère, je me prends une erreur de segmentation en pleine figure (aïeuhhh, ça picote). Ca ressemble à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    char *data = mon_header_http ;
    int i = substrlen (data, "\n");
    strncpy (data+i, "\0", 1) ;
    Quand je change la valeur de i pour mettre un bête chiffre, ça fonctionne.

    J'arrive pas du tout où ça bloque. Quelqu'un de plus expérimenté voir mon erreur ? J'espère que je suis clair

    Merci d'avance

    Enjoy

    The lsd

  2. #2
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    Est-ce que tu as alloué de la mémoire pour 'data' ?
    Si tu as affecté une chaîne telle quelle à ton pointeur 'data' il est normal que tu aies une erreur de segmentation parce que la chaîne pointée n'est pas modifiable.

    Pourquoi tu utilises strstr et pas strchr ? strchr recherche 1 caractère dans ta chaîne, strstr recherche une chaîne dans une autre.

    Plutôt que d'utiliser strncpy tu pourrais tout simplement affecter ta valeur : data[i] = '\0';

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7
    Par défaut
    Citation Envoyé par Pouet_forever Voir le message
    Est-ce que tu as alloué de la mémoire pour 'data' ?
    Si tu as affecté une chaîne telle quelle à ton pointeur 'data' il est normal que tu aies une erreur de segmentation parce que la chaîne pointée n'est pas modifiable.
    ben je l'ai affecté, euhhh oui normalement... 'fin je pense quoi ! Vu que quand je modifie la chaine en mettant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int i = 20;
    strncpy (data+i, "\0", 1) ;
    la chaîne data est bien modifiée. Donc ça devrait être bon. Et je vais poser la question alakon, comment je l'alloue, avec malloc ? Sauf que je connais pas la taille de ma chaine, donc c'pas pratique.


    Citation Envoyé par Pouet_forever Voir le message
    Pourquoi tu utilises strstr et pas strchr ? strchr recherche 1 caractère dans ta chaîne, strstr recherche une chaîne dans une autre.
    Parce que ! C'est le première que j'ai trouvé, donc j'ai pris celle ci :p Mais bon, je vais surement avoir besoin de trouver \r, \n, ou \r\n, donc ça dérange pas.


    Citation Envoyé par Pouet_forever Voir le message
    Plutôt que d'utiliser strncpy tu pourrais tout simplement affecter ta valeur : data[i] = '\0';
    C'est pas un peu crade comme méthode, ça fait pas propre je trouve, mais je me trompe peut être ?

    Enjoy

    The lsd

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 836
    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 836
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par the lsd Voir le message
    ben je l'ai affecté, euhhh oui normalement... 'fin je pense quoi ! Vu que quand je modifie la chaine en mettant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int i = 20;
    strncpy (data+i, "\0", 1) ;
    la chaîne data est bien modifiée. Donc ça devrait être bon.
    Ouch cte lacune. En partant comme ça tu vas droit au mur.
    Pour gagner en rapidité, le C ne vérifie jamais rien, partant du principe que "le programmeur sait ce qu'il fait". Ce qui t'autorise donc, en terme de code, à écrire 15 int dans un tableau de 10. Les 5 autres iront écraser une autre variable.
    Donc ça compilera, ça pourra même marcher un temps. Mais un jour ou l'autre...

    C'est à toi de toujours t'assurer que ce que tu stockes a bien la place d'être stocké. Et que si tu tapes dans tab[n] alors n est bien inclus dans les limites du tableau.

    Citation Envoyé par the lsd Voir le message
    Et je vais poser la question alakon, comment je l'alloue, avec malloc ? Sauf que je connais pas la taille de ma chaine, donc c'pas pratique.
    2 solutions
    1) tu connais pas la taille mais tu peux la connaitre (par le biais d'une fonction d'info quelconque) donc tu fais char *chaine=malloc(n * sizeof(char))
    2) tu connais pas la taille et tu ne peux pas la connaitre. Alors il te faut programmer un algo de ce genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    déclarer un char *chaine=NULL, un size_t taille_allouée=0 et un size_t indice=0
    tant que lecture 1 caractère ok
    faire
        si indice=taille_allouée
        alors
              augmenter taille_allouée de B caractères
              chaine=realloc(chaine, taille_allouée * sizeof(char))
        fin si
     
        chaine[indice]=caractère_lu
        indice++
    fin faire
    De cette façon, t'es toujours sûr d'avoir assez de mémoire. Et en utilisant des tampons de taille "B" ça évite les realloc (lourds) à chaque fois que tu dois insérer un élément (surtout que tu peux, si tu le désires quand-même, positionner B à 1). Et en initialisant ton tableau à NULL et tes variables à 0, t'es sûr que t'auras un premier malloc avant toute insertion (le premier if est forcément vrai et quand le tableau initial est à NULL, realloc se comporte comme malloc).
    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]

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ouch cte lacune. En partant comme ça tu vas droit au mur.
    Pour gagner en rapidité, le C ne vérifie jamais rien, partant du principe que "le programmeur sait ce qu'il fait". Ce qui t'autorise donc, en terme de code, à écrire 15 int dans un tableau de 10. Les 5 autres iront écraser une autre variable.
    Donc ça compilera, ça pourra même marcher un temps. Mais un jour ou l'autre...

    C'est à toi de toujours t'assurer que ce que tu stockes a bien la place d'être stocké. Et que si tu tapes dans tab[n] alors n est bien inclus dans les limites du tableau.
    Ouais, je sais ça, mais je suis toujours dans les bornes de ma variables, puisque i est forcément inférieur au nombre de caractère de data. Donc ça devrais forcément être bon.

    Citation Envoyé par Sve@r Voir le message
    2 solutions
    1) tu connais pas la taille mais tu peux la connaitre (par le biais d'une fonction d'info quelconque) donc tu fais char *chaine=malloc(n * sizeof(char))
    2) tu connais pas la taille et tu ne peux pas la connaitre. Alors il te faut programmer un algo de ce genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    déclarer un char *chaine=NULL, un size_t taille_allouée=0 et un size_t indice=0
    tant que lecture 1 caractère ok
    faire
        si indice=taille_allouée
        alors
              augmenter taille_allouée de B caractères
              chaine=realloc(chaine, taille_allouée * sizeof(char))
        fin si
     
        chaine[indice]=caractère_lu
        indice++
    fin faire
    De cette façon, t'es toujours sûr d'avoir assez de mémoire. Et en utilisant des tampons de taille "B" ça évite les realloc (lourds) à chaque fois que tu dois insérer un élément (surtout que tu peux, si tu le désires quand-même, positionner B à 1). Et en initialisant ton tableau à NULL et tes variables à 0, t'es sûr que t'auras un premier malloc avant toute insertion (le premier if est forcément vrai et quand le tableau initial est à NULL, realloc se comporte comme malloc).
    Bon, ça ok, je sais faire. Mais est ce qu'il faut que je le fasse quand même pour mon char *data ?

    Enjoy

    The lsd

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7
    Par défaut
    Bon, alors, après plusieurs tests, je suis heureux de vous apprendre que... rien n'a changé, ça ne fonctionne toujours pas. malloc ou pas, strncpy ou directement avec data[i].
    Ca ne peut venir que de ma fonction substrlen. Quand je la change, pour mettre return 20 par exemple, tout va bien. Mais je vois pas d'erreur dans cette fonction. Quelqu'un en voit une ?

    Enjoy

    The lsd

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

Discussions similaires

  1. Syntaxe de recherche de position d'un caractère ???
    Par toyyo dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 01/07/2011, 09h30
  2. Réponses: 4
    Dernier message: 09/09/2009, 10h59
  3. Réponses: 3
    Dernier message: 03/04/2008, 15h29
  4. Réponses: 2
    Dernier message: 19/11/2007, 16h53
  5. Réponses: 6
    Dernier message: 20/02/2006, 22h13

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