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 :

Problème lors de la réécriture de strncat


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Inscrit en
    Décembre 2009
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 5
    Par défaut Problème lors de la réécriture de strncat
    Bonjour,
    j'ai une interro très prochaine en C , et donc j'ai décidé de refaire une des anciennes interro , histoire de bien gérer .. Seulement voilà cela fait plusieurs heures que je bloque sur la réécriture de strncat, où on ne peut pas faire d'allocation mémoire ...
    D'abord j'ai fait tenté le coup avec un tableau de caractère , tout fonctionnait bien jusqu'à ce que je sois obligé de return mon tableau, ce qui est pas évident sans allocation mémoire ... Ensuite je suis donc allé voir sur internet le code de strncat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stddef.h> /* size_t */
    char *strncat(char *dest, const char *src, size_t n)
    {
        char *ret = dest;
        while (*dest)
            dest++;
        while (n--)
            if (!(*dest++ = *src++))
                return ret;
        *dest = 0;
        return ret;
    }
    Je l'ai copié/collé, et visiblement ça ne fonctionne pas De toute façon il est pas très parlant, donc j'ai décidé de le faire à ma sauce :
    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
    char * strncat2013 (char* dest,const char * src, size_t count){
        char *ret=dest;
        while(*dest != 0) {
            dest++;
     
        }
     
        while (count > 0) {
            dest++;
            *dest=*src;
            src++;
            if (*src ==0){
                *dest=0;
                return ret;
            }
        }
        *dest=0;
        return ret;
     
        }
    Et la même erreur, ou plutôt pas d'erreur : ça s'execute, la fenêtre reste noire et j'ai juste un message : le programme a cessé de fonctionner !
    j'ai essayé de voir d'où vient le problème (en mettant des printf un peu partout) , et visiblement c'est cet idiot de qui ne veut pas fonctionner, et qui fait tout planter !

    Pourriez vous m'aider?
    Merci
    Voici mon code en entier

    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    #include <stdio.h>
    #include <string.h>
    #include <stddef.h>
     
     
     
    char*strncat2013 (char* dest,const char * src, size_t count);
    int main(void)
    {
        char * dest;
        const char * src;
     
     
        dest="truc";
        src="chose";
       strncat2013(dest, src, 10);
        return 0;
    }
     
    char * strncat2013 (char* dest,const char * src, size_t count){
        char *ret=dest;
     
        while(*dest != 0) {
            dest++;
     
        }
     
        while (count > 0) {
            dest++;
            *dest=*src;
            src++;
            if (*src ==0){
                *dest=0;
                return ret;
            }
        }
        *dest=0;
        return ret;
     
        }

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 473
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 473
    Par défaut
    Bonjour,

    Tu te donnes beaucoup de mal pour rien. La man page de Linux pour strncat() donne même un exemple d'implémentation en C tant il est simple, car c'est la manière la plus simple d'expliquer en définitive ce que fait cette fonction.

    strncat() copie — au maximum — n caractères depuis la chaîne source et à la suite de la chaîne de destination. C'est donc à l'utilisateur de prévoir la place suffisante. Ensuite, elle renvoie un pointeur vers le résultat. Comme on n'a fait qu'ajouter des caractères à la chaîne de destination, on pointe donc vers cette même chaîne et il suffit simplement de faire :
    … en fin de programme. :-)

    Pour le reste, il faut détecter le zéro final de la chaîne de destination, ajouter des caractères à partir de cette position, tant que n est non-nul et que le caractère source est lui aussi différent de '\0' et, surtout, il ne faut pas oublier d'ajouter un nouveau terminateur '\0' après la copie.

  3. #3
    Membre du Club
    Inscrit en
    Décembre 2009
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 5
    Par défaut
    Merci pour cette réponse
    Je me suis donc rendu sur la man page,ce qui m'a donné une implémentation beaucoup plus simple, cependant je n'arrive toujours pas à faire fonctionner mon programme .... Voilà ce que je fait :

    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
    #include <stdio.h>
    #include <string.h>
    #include <stddef.h>
     
     
     
    char*strncat2013 (char* dest, const char * src, size_t n);
     
    char* strncat2013(char *dest, const char *src, size_t n)
    {
        size_t dest_len = strlen(dest);
        size_t i;
     
        for (i = 0 ; i < n && src[i] != '\0' ; i++)
            dest[dest_len + i] = src[i];
        dest[dest_len + i] = '\0';
     
        return dest;
    }
    int main(void)
    {
        char * dest;
        const char * src;
     
        dest="truc";
        src="chose";
        strncat2013(dest, src, 20);
        return 0;
    }
    et j'ai toujours ce fameux "a cessé de fonctionner" lorsque j'execute mon programme fraichement compilé :/
    ça coince à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dest[dest_len + i] = src[i];

    EDIT: en fait, il faut que mes chaines soient tableaux de caractères , il n'est pas possible que ça fonctionne si ce n'est pas le cas ?

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Tu commets deux erreurs :
    • dest="truc"; : la chaine "truc" se situe dans une zone non-modifiable. Voir FAQ.
    • Et même si cette chaine était modifiable, elle ne compterait que 5 caractères 't', 'r', 'u', 'c', '\0' tu ne pourrais rien mettre à la suite comme tu tentes de le faire sans dépasser de la zone mémoire disponible.


    Deux solutions donc :
    • Comme tu l'as évoqué : utiliser un tableau qui lui serait modifiable. Il faudra alors prévoir une taille suffisamment grande pour contenir la chaine finale 't', 'r', 'u', 'c', 'c', 'h', 'o', 's', 'e', '\0' soit 10 caractères.
      Il faudra aussi veiller à fournir un troisième argument à strncat2013() au maximum de cette taille.
    • Effectuer une allocation de mémoire avec malloc() (idem de taille suffisante), y copier la première partie avec strcpy. Sans oublier de libérer la mémoire à la fin.


    Passons à ta fonction strncat2013()
    Tu souhaites ne pas dépasser les n caractères, et pour ceci, tu vérifies i < n dans ta boucle... Mais tu effectues le par cours suivant :
    Attention donc que c'est dest_len + i qui ne doit pas dépasser n

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 473
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 473
    Par défaut
    Citation Envoyé par siedblack Voir le message
    Merci pour cette réponse Je me suis donc rendu sur la man page,ce qui m'a donné une implémentation beaucoup plus simple, cependant je n'arrive toujours pas à faire fonctionner mon programme .... Voilà ce que je fait :
    Euh… oui, enfin, l'honnêteté intellectuelle nous pousse à souligner que tu as copié-collé le code de la man page dans ta fonction. Mais soit ! :-)

    Ce n'est pas forcément une mauvaise chose en soi si le code est efficace, mais ça ne sert absolument à rien si tu ne comprends pas ce que tu fais.

    et j'ai toujours ce fameux "a cessé de fonctionner" lorsque j'execute mon programme fraichement compilé :/
    « a cessé de fonctionner » est une expression laconique indiquant que ton programme a planté et que c'est le micro-processeur qui a stoppé son exécution pour une raison particulière, cette raison étant le plus souvent une « segfault » comme on dit sous Unix. Ça veut dire que ton programme était hors de contrôle et qu'il s'est amusé à écrire en dehors de l'espace que le système lui a alloué. Tant qu'il écrase ses propres variables, ça le regarde. S'il veut écrire chez les copains, ça ne va plus.

    EDIT: en fait, il faut que mes chaines soient tableaux de caractères , il n'est pas possible que ça fonctionne si ce n'est pas le cas ?
    En fait, « chaîne de caractères » et « tableau de caractères » sont deux choses pour ainsi dire équivalentes en C. Sache simplement que quand tu manipules des types dans ce langage, il n'y a jamais d'allocation implicite de la mémoire. Soit tu alloues des variables locales dans la pile (lesquelles peuvent être des tableaux) en les déclarant en début de bloc, soit tu demandes explicitement au système d'exploitation de te réserver de l'espace quelque part en mémoire (avec malloc()), soit tu utilises des fonctions de certaines bibliothèques qui vont faire ce travail à ta place mais, même dans ce cas, il te faudra quand même libérer l'espace à la main quand tu auras fini.

    Ceci veut dire que si tu n'as pas explicitement alloué de l'espace à ta chaîne, il n'y a pas de raison que ça marche tout seul. Cela signifie également que tout ce que fait cette fonction, c'est copier des caractères depuis un emplacement en mémoire vers un autre emplacement. Elle ne vérifie absolument pas si cet espace est valide et en aucun cas n'en alloue elle-même.

    Quand tu écris "chaine" entre guillemets, tu définis une chaîne de caractères écrite « en dur » au sein de ton programme. Comme le contenu de cette chaîne est défini avant même le début de l'exécution, il doit donc faire partie du code. Ton compilateur l'inscrit donc au sein de l'exécutable qui va être ensuite chargé en mémoire et quand tu t'y réfères, tu obtiens un pointeur qui te renvoie directement où elle se trouve. Si tu essaies d'utiliser strncat() directement dessus, tu essaies d'ajouter des caractères dans la zone réservée au code, d'une part, et tu vas écraser tout ce qui suit immédiatement cette chaîne.

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

Discussions similaires

  1. Problème lors d'encodage dans un Maskedit
    Par panthere6 dans le forum Bases de données
    Réponses: 2
    Dernier message: 08/06/2004, 06h35
  2. Problème lors d'un Update sur une date
    Par Nany dans le forum ASP
    Réponses: 3
    Dernier message: 19/05/2004, 22h37
  3. Problème lors du EXTEND d'un tableau
    Par banana31 dans le forum Oracle
    Réponses: 14
    Dernier message: 10/02/2004, 10h58
  4. Problème lors du chargement
    Par carlito dans le forum Flash
    Réponses: 26
    Dernier message: 06/01/2004, 15h21
  5. Réponses: 2
    Dernier message: 17/08/2003, 20h07

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