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 :

Insertion d'un chaîne de caractères dans une autre à une position donnée


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2018
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 25
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2018
    Messages : 18
    Points : 1
    Points
    1
    Par défaut Insertion d'un chaîne de caractères dans une autre à une position donnée
    Bonjour,

    Je souhaiterais créer une fonction void strinsert(char*M,char*T,int i) qui insère un mot T dans un mot M à la position i, en utilisant les fonctions du string.h et les tableaux dynamiques
    Aidez-moi svp

  2. #2
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 625
    Points : 1 559
    Points
    1 559
    Par défaut
    Hello,

    Il faut déplacer les caractères de la position M[i] en M[i+strlen(T)] sur une longueur de strlen(M[i])+1 (pour copier le \0) avec movmem() memmove(), puis faire un memcpy() de strlen(T) caractères de T en M[i].

    Bon, à part ça, peux-tu nous montrer ce que tu as essayé ?

    Ici tu auras de l'aide, mais pas du code.

    Edit: correction grâce à Sve@r: bien sûr, pas movmem() mais memmove()
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Bonjour

    S'agit-il d'un exercice d'école ou d'un travail pour toi ?
    Si c'est pour toi alors tu peux utiliser les fonctions memmove et conseurs citées par edgarjacobs. Si c'est pour l'école, alors à mon avis il te faudra écrire tout le code toi-même (si j'étais prof c'est ce que je demanderais). Dans ce cas, en admettant que le mot "T" ait une longueur de "t" caractères, il te faut décaler les caractères du mot "M" situés à la position "i" de "t" caractères. Une fois ces caractères décalés, tu pourras alors y mettre ceux du mot "T".
    Attention, le décalage doit se faire en commençant par la fin et en remontant vers la position "i". Parce que si tu veux insérer "xy" dans le mot "Hello" à la position (par exemple) 2 (donc au "e"), si tu commences par la gauche et que tu déplaces le "e" de 2 positions, alors le mot deviendra "Heleo". Ensuite tu décales le "l" et ça devient "Helel". Et ensuite tu arrives à la 4° position qui contient maintenant un "e" que tu décales encore et le mot devient "Helee" puis "Helel" puis "Helele" puis au final "Helelel".
    Donc tu commences par la fin et "Hello" devient alors "Hello.o" puis "Hellolo" puis "Hellllo" puis "Helello". Et ensuite tu insères "xy" à la position "2" et le mot devient au final "Hxyello" ce qui correspond à ce qui est attendu.

    Et bien évidemment, on peut corriger ton code mais on ne t'en fournira pas un tout fait.
    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 averti
    Homme Profil pro
    très occupé
    Inscrit en
    Juillet 2014
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : très occupé

    Informations forums :
    Inscription : Juillet 2014
    Messages : 137
    Points : 411
    Points
    411
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Bonjour

    S'agit-il d'un exercice d'école ou d'un travail pour toi ?
    Si c'est pour toi alors tu peux utiliser les fonctions memmove et conseurs citées par edgarjacobs. Si c'est pour l'école, alors à mon avis il te faudra écrire tout le code toi-même
    (...)
    Je ne pense pas qu'il doive recoder memmove si "en utilisant les fonctions du string.h" indiquée par joujou98 dans son message d'origine fait partie de son énoncé, en effet, c'est bien une fonction accessible par string.h ...

    En ce qui concerne l'exigence "en utilisant les (...) tableaux dynamiques", c'est un peu plus flou, car cette notion n'existe pas vraiment en C. Il est sans doutes question d'une zone mémoire pointée par un pointeur sur char, allouée avec malloc et qu'on pourrait agrandir avec realloc pour ajuster la capacité d'accueil de la zone mémoire de destination.

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par -Eks- Voir le message
    Je ne pense pas qu'il doive recoder memmove si "en utilisant les fonctions du string.h" indiquée par joujou98 dans son message d'origine fait partie de son énoncé, en effet, c'est bien une fonction accessible par string.h ...
    Bien vu
    Mais ça facilite grandement le TP !!! Punaise en 2 lignes c'est réglé quoi.

    Citation Envoyé par -Eks- Voir le message
    allouée avec malloc et qu'on pourrait agrandir avec realloc pour ajuster la capacité d'accueil de la zone mémoire de destination.
    Ah, là je suis moins d'accord. La taille finale est connue dès le départ puisque c'est la somme des deux chaines. Donc un malloc suffit. Pas besoin d'agrandir
    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]

  6. #6
    Membre averti
    Homme Profil pro
    très occupé
    Inscrit en
    Juillet 2014
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : très occupé

    Informations forums :
    Inscription : Juillet 2014
    Messages : 137
    Points : 411
    Points
    411
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    La taille finale est connue dès le départ puisque c'est la somme des deux chaines. Donc un malloc suffit. Pas besoin d'agrandir
    Notre ami nous dit que le prototype est void strinsert(char*M,char*T,int i), et que la fonction "insert un mot T dans un mot M à la position i" (sic). On peut déduire donc que la fonction sert à obtenir une chaîne plus grande que la chaîne de départ, et que la chaîne plus grande et la chaîne de départ sont toutes deux pointées par M, comme le suggère aussi le type void de la fonction, qui ne sert donc pas à récupérer un résultat.

    Il faudra bien, en tout état de cause, décider qui a la responsabilité de s'assurer que l'espace alloué sur M est suffisant et de traiter le cas s'il ne l'est pas. Cela peut être la fonction elle même, ou la fonction appelante.

    • Si l'on prend le parti que cela soit la fonction strinsert, comme le prototype de la fonction ne comprend pas la taille mémoire allouée sur M, tout ce que peut faire la fonction c'est faire un realloc ajusté à la taille effectivement nécessaire au stockage final (qui suppose donc que M ait été initialement allouée avec un malloc préalable).
    • Si l'on décide que c'est de la responsabilité de la fonction appelante que de s'assurer que l'espace mémoire alloué pointé par M est suffisant, la fonction strinsert prendra pour acquis que l'espace est suffisant, et alors la façon dont la mémoire est allouée sur M importe peu, malloc ou pas, et M pourrait être un tableau de char dans lequel la fonction appelante s'assure que l'espace disponible est suffisant (dans ce dernier cas, pas d'allocation dynamique. Mais alors, je ne sais pas si on pourrait parler de "tableau dynamique" selon l'énoncé...)


    Le 2ème type d'approche ferait de cette fonction une fonction relativement délicate à appeler du point de vue sécurité, un peu comme strcpy à laquelle on préfère strncpy voire strncpy_s si on est en C11.

    Les deux choix sont possibles, mais le premier est un peu une approche tout en un, gérant effectivement dynamiquement l'espace nécessaire au plus juste (le realloc peut agrandir, comme diminuer l'espace), et me semble d'avantage correspondre à l'esprit de la question portant sur des "tableaux dynamiques", avec la seule contrainte que la mémoire pointée par M doit être allouée au préalable avec malloc, tout en laissant la fonction appelante gérer l'affectation initiale et la libération finale de la mémoire.

    Voilà, en explication plus longue, pourquoi je parlais de realloc

  7. #7
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Une fonction avec une telle signature :

    • ne prend aucun de ses paramètres par référence ;
    • ne renvoie rien.

    On ne peut donc pas y réaliser d'allocation dynamique. Le dilemme est vite expédié.


    Citation Envoyé par -Eks- Voir le message
    une fonction relativement délicate à appeler du point de vue sécurité, un peu comme strcpy à laquelle on préfère strncpy voire strncpy_s si on est en C11.
    Non, non et non !

    strcpy n'est pas unsafe, il faut arrêter avec ça. Et son équivalent « défensif » n'est sûrement pas strncpy. Je lâche pas l'affaire et serai encore là pour le répéter la prochaine fois !

  8. #8
    Membre averti
    Homme Profil pro
    très occupé
    Inscrit en
    Juillet 2014
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : très occupé

    Informations forums :
    Inscription : Juillet 2014
    Messages : 137
    Points : 411
    Points
    411
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Une fonction avec une telle signature :

    • ne prend aucun de ses paramètres par référence ;
    • ne renvoie rien.

    On ne peut donc pas y réaliser d'allocation dynamique. Le dilemme est vite expédié.
    Tu as tout à fait raison, au temps pour moi,... pour modifier l'adresse mémoire pointée par un pointeur sur char, le prototype devrait être char ** M et pas char * M, qui ne permettrait effectivement de modifier que l'adresse pointée par une copie du pointeur.

    Citation Envoyé par Matt_Houston Voir le message
    Non, non et non !

    strcpy n'est pas unsafe, il faut arrêter avec ça. Et son équivalent « défensif » n'est sûrement pas strncpy. Je lâche pas l'affaire et serai encore là pour le répéter la prochaine fois !
    Bravo ! il faut avoir des convictions, il vaut mieux un débordement de mémoire qu'une chaîne mal terminée. Heureusement que j'ai parlé des fonctions C11 (d'ailleurs strcpy_s serait mieux), sinon c'est pas la fessée en public mais le lynchage qui m'attendais. T'es énervé toi, non ?

    Si tu me permets cette observation, strcpy (et effectivement strncpy) est loin d'être populaire en termes de sécurité :

    https://wiki.sei.cmu.edu/confluence/...cent+functions par exemple,
    https://rules.sonarsource.com/c/RSPEC-1081

    Sur ce dernier lien de l'éditeur de sonarlint, on peut lire :

    Insecure functions "strcpy", "strcat" and "sprintf" should not be used

    When using legacy C functions such as strcpy, it's up to the developer to make sure the size of the buffer to be written to is large enough to avoid buffer overruns. If this is not done properly, it can result in a buffer overflow, causing the program to crash at a minimum. At worst, a carefully crafted overflow can cause malicious code to be executed.

    In such cases, it's better to use an alternate, secure, function, such as strlcpy(), strlcat() and snprintf(), which allows you to define the maximum number of characters to be written to the buffer. However, since strlcpy() and strlcat() are part of the BSD library, they might not be available, in which case strncpy() and strncat() should be used instead, but be aware that they don't guarantee the string will be null-terminated.

    Noncompliant Code Example

    (...)
    strcpy(str, message); // Noncompliant

    Compliant Solution

    (...)
    strncpy(str, message, sizeof(str) -1); // Leave room for null
    str[sizeof(str) - 1] = '\0'; // Make sure the string is null-terminated
    Cela dit je me suis encore trompé (gulp), car c'est par erreur que j'ai fait référence aux fonctions de la famille strcpy : je voulais faire un parallèle avec la famille des fonctions standard de concaténation (et pas de copie) strcat, et qui ressemble d'avantage dans l'idée à celle qui est le sujet de ce fil, c'est à dire ajouter une chaîne à une autre préexistante, à l'exception du fait qu'elle insère le contenu de la chaîne à la fin au lieu d'une position donnée.

    Donc, mea culpa encore.

    Si on se résume, et pour revenir aux questions de joujou98 on a déterminé :

    • que la fonction pouvait se contenter d'utiliser memmove compte tenu de l'énoncé,
    • et qu'elle ne pouvait que déléguer la gestion de l'allocation de la mémoire à la fonction appelante.


    du coup, l'exercice est vraiment simple.

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par -Eks- Voir le message
    Notre ami nous dit que le prototype est void strinsert(char*M,char*T,int i), et que la fonction "insert un mot T dans un mot M à la position i" (sic). On peut déduire donc que la fonction sert à obtenir une chaîne plus grande que la chaîne de départ, et que la chaîne plus grande et la chaîne de départ sont toutes deux pointées par M, comme le suggère aussi le type void de la fonction, qui ne sert donc pas à récupérer un résultat.
    Ah oui je comprends mieux mais je n'avais pas vu ça comme ça. Si on m'avait demandé une telle fonction je serais parti du postulat que c'est à l'appelant de gérer (tout comme c'est à lui de gérer quand il utilise strcpy()) et dans ce cas, un malloc suffit.

    Citation Envoyé par -Eks- Voir le message
    Il faudra bien, en tout état de cause, décider qui a la responsabilité de s'assurer que l'espace alloué sur M est suffisant et de traiter le cas s'il ne l'est pas. Cela peut être la fonction elle même, ou la fonction appelante.
    Cela peut faire l'objet d'un nouveau débat qui serait intéressant. Perso je suis pour la simplicité donc c'est à l'appelant de gérer. Déjà ça rend la fonction plus "universelle" (elle pourra recevoir indifféremment un tableau de char ou un pointeur alloué). Et aussi plus simple à coder (simply is better than complex )

    Citation Envoyé par -Eks- Voir le message
    Si tu me permets cette observation, strcpy (et effectivement strncpy) est loin d'être populaire en termes de sécurité. Sur ce dernier lien de l'éditeur de sonarlint, on peut lire :
    Insecure functions "strcpy", "strcat" and "sprintf" should not be used

    When using legacy C functions such as strcpy, it's up to the developer to make sure the size of the buffer to be written to is large enough to avoid buffer overruns. If this is not done properly, it can result in a buffer overflow, causing the program to crash at a minimum. At worst, a carefully crafted overflow can cause malicious code to be executed.

    In such cases, it's better to use an alternate, secure, function, such as strlcpy(), strlcat() and snprintf(), which allows you to define the maximum number of characters to be written to the buffer. However, since strlcpy() and strlcat() are part of the BSD library, they might not be available, in which case strncpy() and strncat() should be used instead, but be aware that they don't guarantee the string will be null-terminated.

    Noncompliant Code Example

    (...)
    strcpy(str, message); // Noncompliant

    Compliant Solution

    (...)
    strncpy(str, message, sizeof(str) -1); // Leave room for null
    str[sizeof(str) - 1] = '\0'; // Make sure the string is null-terminated
    Hum, non désolé. Là je suis aussi d'accord avec matt_Houston (mais sans te fesser ). Et ce n'est pas parce que sonarlint dit un truc que ce truc est forcément vrai. Surtout quand il conseille sizeof(str) sans se préoccuper de savoir si str est un tableau (ok ça le fera) ou bien un pointeur !!!

    Le C est un langage hautement permissif. C'est une philosophie volontairement et entièrement assumée par son concepteur. Si le codeur qui utilise strcpy() n'est pas foutu de gérer sa source et sa destination ben ça reste son problème et c'est tant pis pour sa tronche. Sinon autant dire que int tab[10] est unsafe parce qu'on peut écrire tab[500]=123.

    Les seuls trucs unsafe en C sont les trucs directement récupérés de l'extérieur sans contrôle. On aura bien évidemment gets() qui arrive en premier et oui on pourra avoir aussi strcpy mais uniquement dans cette syntaxe strcpy(dest, argv[x]) parce que argv[x] est une donnée extérieure non maitrisable par le codeur. Et donc en réalité ce n'est pas strcpy() le souci mais argv[x]. Et si, pour résoudre ce danger, tu utilises strncpy() c'est parce que tu te méfies non pas de strcpy mais bien de argv[x].
    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]

  10. #10
    Membre averti
    Homme Profil pro
    très occupé
    Inscrit en
    Juillet 2014
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : très occupé

    Informations forums :
    Inscription : Juillet 2014
    Messages : 137
    Points : 411
    Points
    411
    Par défaut
    Ah.. j'aurai essayé de revenir au sujet du post initial.

    On en est un peu loin,... mais s'il faut débattre, allons y.

    Citation Envoyé par Sve@r Voir le message
    Ah oui je comprends mieux mais je n'avais pas vu ça comme ça. Si on m'avait demandé une telle fonction je serais parti du postulat que c'est à l'appelant de gérer (tout comme c'est à lui de gérer quand il utilise strcpy()) et dans ce cas, un malloc suffit.


    Cela peut faire l'objet d'un nouveau débat qui serait intéressant. Perso je suis pour la simplicité donc c'est à l'appelant de gérer. Déjà ça rend la fonction plus "universelle" (elle pourra recevoir indifféremment un tableau de char ou un pointeur alloué). Et aussi plus simple à coder (simply is better than complex )
    Je suis d'accord avec cette approche, qui a aussi ma préférence et qui est aussi celle adoptée par les fonctions standard du C. Je n'ai soulevé l'approche alternative de réallocation par la fonction que parce qu'elle paraissait correspondre à l'esprit de la question portant sur des "tableaux dynamiques".

    Cependant, comme l'observé succinctement par Matt_Houston, le prototype proposé n'est pas adéquat. Comme détaillé dans ma réponse précédente, le prototype provenant apparemment de l'énoncé ne permettrait pas la gestion utile de la réallocation par la fonction, le passage du pointeur par référence nécessiterait en effet de passer char ** M. Avec char * M, la fonction appelante ne verrait pas une éventuelle réallocation se faisant dans la fonction sur une autre adresse mémoire (ce qui peut se produire avec realloc)

    Citation Envoyé par Sve@r Voir le message
    Hum, non désolé. Là je suis aussi d'accord avec matt_Houston (mais sans te fesser ).
    Cool !

    Citation Envoyé par Sve@r Voir le message
    Et ce n'est pas parce que sonarlint dit un truc que ce truc est forcément vrai.
    Je n'utilise pas leur produit. J'ai juste trouvé intéressant de montrer une opinion d'un éditeur de produit de sécurisation de code, décourageant l'usage de strcpy, et indiquant que strncpy (qui n'est pas parfaite) peut être utilisée à défaut de mieux, tout en remédiant à ses limitations. Il n'inventent rien, les références MITRE, CERT et cie de leur entrée sont dans leur base.

    Je ne suis pas non plus un intégriste des recommandations des MITRE et autres CERT. Je voulais juste faire observer que mon opinion "fonction relativement délicate à appeler du point de vue sécurité, un peu comme strcpy à laquelle on préfère strncpy voire strncpy_s si on est en C11" peut être partagée par d'autres.

    Citation Envoyé par Sve@r Voir le message
    Surtout quand il utilise sizeof(str) sans se préoccuper de savoir si str est un tableau (ok ça le fera) ou bien un pointeur !!!
    Oui, leur code fonctionne avec sizeof pour un tableau. Si tu as alloué au préalable de la mémoire avec malloc, il faudra que tu gardes l'information sur la taille du tampon. Les exemples de code du SEI CERT Coding Standards sont plus complets (mais il faut lire 3 ou 4 liens différents avec de multiples cas correspondant à des risques différents et préparer 3 cachets d'aspirine).

    Citation Envoyé par Sve@r Voir le message
    Le C est un langage hautement permissif. C'est une philosophie volontairement et entièrement assumée par son concepteur. Si le codeur qui utilise strcpy() n'est pas foutu de gérer sa source et sa destination ben ça reste son problème et c'est tant pis pour sa tronche. Sinon autant dire que int tab[10] est unsafe parce qu'on peut écrire tab[500]=123.

    Les seuls trucs unsafe en C sont les trucs directement récupérés de l'extérieur sans contrôle. On aura bien évidemment gets() qui arrive en premier et oui on pourra avoir aussi strcpy mais uniquement dans cette syntaxe strcpy(dest, argv[x]) parce que argv[x] est une donnée extérieure non maitrisable par le codeur. Et donc en réalité ce n'est pas strcpy() le souci mais argv[x]. Et si, pour résoudre ce danger, tu utilises strncpy() c'est parce que tu te méfies non pas de strcpy mais bien de argv[x].
    On est d'accord, les problèmes surviennent avec une source non maîtrisée par le programme.

    S'agissant de strcpy, j'ai parlé de "fonction délicate à appeler du point de vue sécurité" et pas de fonction "unsafe" ou de fonction à rayer du langage C. strcpy fait peser sur le programmeur un certain nombre de vérifications préalables. Si elles sont oubliées ou mal faites, les conséquences peuvent être catastrophiques et introduire un risque d'attaque par débordement de tampon, et d'exécution de code malveillant.

    strncpy, qui effectivement n'avait pas été spécialement conçue pour sécuriser strcpy, peut néanmoins être utilisée pour traiter le risque de débordement de tampon. Elle apporte son lot de problèmes, mais si tu veilles à terminer ta chaîne et que le padding superflu ne te gêne pas, c'est mieux que rien, si tu dois faire du code portable, que tu ne peux pas utiliser les fonctions BSD préconisées ci-dessus, ou les fonctions C11.

    Je ne prétend pas être une autorité en la matière, je ne fais que faire part de ma compréhension et du pourquoi de mon commentaire, qui me semblait très anodin et ne pas mériter autant "d'attentions".

  11. #11
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2018
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 25
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2018
    Messages : 18
    Points : 1
    Points
    1
    Par défaut VOILA MON ESSAIE
    corrigez moi svp


    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
     
    void ModifierCapacite(char*M,char*T)
    {  char*tmp ;
            tmp=(char*)malloc((strlen(M))*sizeof(char));
             if(!tmp)
           {
           exit(EXIT_FAILURE);
            }
            strcpy(tmp,M);
            free(M);
            M=(char*)malloc((strlen(M)+strlen(T)) *sizeof(char));
            strcpy(M,tmp);
     
    }
     
    void strinsert (char*M, char*T,int i)
    {
    if (strlen(M)<=strlen(T))
    {   ModifierCapacite(M,T);
     
        for (int j=strlen(M-1);j>0;j++)
        {
            M[j+2]=M[j];
        }
     
      for (int j=i-1;j<=strlen(T);j++)
      {
          strcpy(M[j],T[j-1]);
      }
      printf("final copied string %s",M);
    }
    }

  12. #12
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par joujou98 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void ModifierCapacite(char*M,char*T)
    {  char*tmp ;
            tmp=(char*)malloc((strlen(M))*sizeof(char));
             if(!tmp)
           {
           exit(EXIT_FAILURE);
            }
            strcpy(tmp,M);
            free(M);
            M=(char*)malloc((strlen(M)+strlen(T)) *sizeof(char));
            strcpy(M,tmp);
     
    }
    Là déjà je ne comprends pas trop ta façon de faire. Tu alloues "tmp", tu lui copies "M", puis tu libères "M" pour l'allouer de nouveau différemment (tu ne connais pas realloc ???) et tu y copies "tmp" que tu oublies de libérer en plus. Accessoirement tu présupposes que "M" est un pointeur qui aura été alloué ailleurs ce qui interdit donc d'appeler ton truc avec un tableau. Et de toute façon, M est un pointeur oui mais c'est un pointeur local à la fonction donc quand la fonction se termine, il disparait et tout ce qui a été fait sous la forme M=quoi que ce soit est perdu (ce qu'avait déjà écrit matt_Houston) donc et surtout ce M=(char*)malloc((strlen(M)+strlen(T)) *sizeof(char)).
    De plus M ayant été libéré, il est devenu interdit d'accès y compris par ce strlen(M). Et enfin on ne caste pas un malloc (mais sur ce dernier point il y a un débat avec aussi de bons arguments pour le cast donc si tu veux le laisser on t'en fera pas grief).

    Citation Envoyé par joujou98 Voir le message
    ModifierCapacite(M,T)
    Tu as dû apprendre qu'une fonction qui veut modifier un truc doit recevoir l'adresse de ce truc. Ben c'est valable aussi quand "truc" est un char étoile. Et la fonction, recevant cette adresse, devra le stocker dans un char étoile étoile.

    Citation Envoyé par joujou98 Voir le message
    corrigez moi svp
    Voilà. Si toutefois tu nous exprimais ton idée ce serait plus facile d'autant plus que je crois la deviner mais que cette idée n'est pas le bon départ.
    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]

  13. #13
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2018
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 25
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2018
    Messages : 18
    Points : 1
    Points
    1
    Par défaut
    J'ai pas vraiment compris .. svp pouvez vous m'expliquer en code

  14. #14
    Membre averti
    Homme Profil pro
    très occupé
    Inscrit en
    Juillet 2014
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : très occupé

    Informations forums :
    Inscription : Juillet 2014
    Messages : 137
    Points : 411
    Points
    411
    Par défaut
    Bonjour joujou98,

    Quelques observations complémentaires à celles de Sve@r.

    Comme indiqué par Sve@r, et discuté plus haut dans ce fil, ton prototype de fonction devrait donc être void ModifierCapacite(char ** M, char * T) ...

    Pour ton allocation de tmp, il faudrait faire tmp = malloc((strlen(*M)) + 1); ...

    Par rapport à ton allocation note que :
    • on alloue la taille de la chaîne + 1, car autrement, avec ton code, tu n'as pas assez d'espace mémoire pour copier le caractère de fin de chaîne '\0' et tu vas déborder la mémoire allouée d'un caractère lors de la copie avec strcpy
    • pour accéder à l'adresse mémoire pointée par le pointeur sur char de la chaîne, on déréférence l'adresse du pointeur avec l'opérateur *
    • il est inutile en C, et même dangereux, de faire un cast sur le résultat de malloc
    • il est inutile de faire une multiplication * sizeof(char) car la norme du C garantit que cela vaut 1, et multiplier par 1 ne change rien

    La suite du code doit être corrigée de la même façon.

    Note qu'en faisant cette fonction, tu réinventes la roue et tu te compliques la vie, puisque la fonction standard du C realloc dont je parlais plus haut aboutirait exactement au même résultat.

    Sans avoir besoin de créer une fonction additionnelle et gérer des pointeurs de pointeurs, tu peux directement faire, par exemple :

    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
    #include <stdio.h>                                                                                                                                                                                                 
    #include <stdlib.h>
    #include <string.h>
     
    int main(void)
    {
        char suite[] = "67890";
        char * stmp = NULL;
     
        char * s2 = malloc(6);
        if (!s2) {
            printf("Erreur : impossible d'allouer la mémoire\n");
            return EXIT_FAILURE;
        }
        strcpy(s2, "12345");
        printf("s2 contient %s\n", s2);
        stmp = realloc(s2, strlen(s2) + strlen(suite) + 1);
        if (!stmp) {
            printf("Erreur : impossible de modifier la quantité "
                    "de mémoire allouée\n");
            return EXIT_FAILURE;
        }
        s2 = stmp;
        strcat(s2, suite);
        printf("s2 contient maintenant %s\n", s2);
     
        return 0;
    }

  15. #15
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2018
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 25
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2018
    Messages : 18
    Points : 1
    Points
    1
    Par défaut
    J'arrive pas à le faire

  16. #16
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par joujou98 Voir le message
    J'ai pas vraiment compris
    Un forum c'est pratique, mais ça ne fait pas tout. Par exemple ça ne peut pas lire un cours de C à ta place !!!

    Citation Envoyé par joujou98 Voir le message
    .. svp pouvez vous m'expliquer en code
    Pfff

    Si tu écris
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void modif(int n) {
    	n=0;
    }
    Ca ne sert à rien car "n" est local à la fonction et donc il est perdu quand la fonction se termine. Et donc tu auras beau écrire ensuite
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main() {
    	int n=500;
    	modif(n);
    }
    "n" vaudra toujours 500. Parce que il ne s'agit pas de la même variable "n" et que la fonction n'a reçu qu'une copie de cette valeur, copie qu'elle a stockée dans sa propre variable locale puis perdue ensuite.

    Pour que ça fonctionne, il est nécessaire de passer l'adresse de la variable à modifier à la fonction...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main() {
    	int n=500;
    	modif(&n);
    }

    ... fonction qui stockera cette adresse dans un pointeur. Et comme il n'y a qu'une seule zone mémoire pour un programme, cette adresse stockée correspondra à l'adresse de la variable à modifier donc la fonction pourra y aller pour la modifier
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void modif(int *pt) {
    	(*pt)=0;
    }

    C'est pour ça qu'on passe des adresse à scanf(). T'as dû apprendre ça quand-même !!!

    Ben ce principe s'applique à tout, y compris aux pointeurs. En écrivant
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void ModifierCapacite(char* M) {
    	M=malloc(...);
    }
     
    int main() {
    	char* M;
    	ModifierCapacite(M);
    }
    Tu n'as fait que reproduire mon premier exemple (moi j'utilise des "int" et toi des "char étoile" mais c'est du détail qui ne change rien au résultat).

    Donc si tu veux faire modifier un pointeur par une autre fonction, il te faut utiliser la même méthode et passer l'adresse de ce pointeur à la fonction qui va le modifier, dans un modèle analogue à mon second exemple

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void ModifierCapacite(char **M) {
    	(*M)=malloc(...);
    }
     
    int main() {
    	char *M;
    	ModifierCapacite(&M);
    }
    Mais là, comme l'a dit Matt_Houston, ce modèle de fonction ne correspond plus à celle qu'on te demande d'écrire (elle reçoit un "char étoile étoile" alors que le modèle montre un "char étoile"). Donc concrètement cette idée que tu as n'est pas bonne (ou du moins ne peut pas être adaptée à la fonction qu'on te demande d'écrire).

    Citation Envoyé par joujou98 Voir le message
    J'arrive pas à le faire
    Explique-nous avec des mots quelle est ton idée pour faire cet exercice (vu que nous on te l'a expliqué mais que tu n'as rien lu de ce qu'on a écrit)...
    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]

  17. #17
    Membre averti
    Homme Profil pro
    très occupé
    Inscrit en
    Juillet 2014
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : très occupé

    Informations forums :
    Inscription : Juillet 2014
    Messages : 137
    Points : 411
    Points
    411
    Par défaut
    Salut Sve@r, et joujou98,

    A titre préalable, joujou98 essaye désormais de faire quelque chose de différent de sa question initiale (ce qui pourrait indiquer que le prototype initial n'était pas une exigence d'un énoncé, mais juste un prototype que joujou98 pensait pouvoir utiliser).

    @Sve@r:

    Tes explications sont très claires et les exemples pertinents, et je pense qu'ils vont clarifier pas mal de choses pour joujou98

    Sur la dernière partie, cependant, je pense que tu es allé plus vite et je suis moins d'accord avec ton exemple de code, qui peut induire en erreur joujou98.

    Citation Envoyé par Sve@r Voir le message
    Donc si tu veux faire modifier un pointeur par une autre fonction, il te faut utiliser la même méthode et passer l'adresse de ce pointeur à la fonction qui va le modifier, dans un modèle analogue à mon second exemple

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void ModifierCapacite(char **M) {
    	(*M)=malloc(...);
    }
     
    int main() {
    	char *M;
    	ModifierCapacite(&M);
    }
    Ton exemple montre correctement comment passer l'adresse d'un pointeur sur char, afin que la fonction appelée puisse modifier le contenu de la variable pointeur, qui n'est pas initialisé dans ton cas. Cependant :

    • La fonction ModifierCapacite() que joujou98 essaye de mettre au point sert visiblement à modifier une capacité de stockage déjà allouée
    • La fonction que joujou98 essaye de faire prend 2 paramètres, qui correspondent visiblement à des pointeurs sur char pointant sur quelque chose, sinon elle n'utiliserait pas strlen() dessus et ne ferait pas ce qu'elle essaye de faire, c'est dire copier temporairement le contenu de la zone mémoire pointé par M ailleurs, la libérer, allouer une zone mémoire plus grande et tenter d'y remettre le contenu
    • Ton exemple écraserait une adresse mémoire existante dans M et ne comprendrait pas d'information quant à "de combien il faut augmenter la capacité" ou comment la "modifier"
    • Ton exemple est valide pour une fonction d'allocation, mais alors le nom ModifierCapacite() est inapproprié et autant faire un prototype char * AllouerMemoire(void) qui évite des complications (mais ce n'est pas ce que joujou98 veut faire)


    Citation Envoyé par Sve@r Voir le message
    Explique-nous avec des mots quelle est ton idée pour faire cet exercice
    @Sve@r et @joujou98 :

    Je pense quant à moi qu'elle a déjà montré ce qu'elle voulait faire avec son dernier code lequel est très "parlant". Ainsi, son code, bien que maladroit, peut être rendu fonctionnel pour aboutir au résultat qu'elle souhaite en le rectifiant, à l'aide des indications éparses qu'elle a déjà reçu, mais qu'elle a visiblement du mal à saisir dans leur globalité ou mettre en oeuvre.

    Citation Envoyé par Sve@r Voir le message
    (vu que nous on te l'a expliqué mais que tu n'as rien lu de ce qu'on a écrit)...
    Ce topic atteint des proportions dantesques sur des sujets non triviaux (y compris sur des sujets éloignés de la question ou des questions posée(s)), avec des informations dispersées et des interventions elliptiques de certains intervenants.

    Je compatis à la situation de joujou98 qui ne doit pas être évidente (surtout si elle est débutante) et je ne lui ferait pas le procès d'intention de n'avoir "rien lu".

    Synthétiser tout cela sous forme de code ne me semblait pas de trop... et j'ai pensé utile de le faire.

    Alors, voilà un exemple :

    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
    void ModifierCapacite(char ** M, char * T)
    {  
        char * tmp;
     
        tmp = malloc((strlen(*M)) + 1);
        if (!tmp) {
            printf("Erreur : impossible d'allouer la mémoire pour tmp\n");
            exit(EXIT_FAILURE);
        }
        strcpy(tmp,*M);
     
        free(*M);
        *M = malloc((strlen(tmp) + strlen(T)) + 1);
        if (!(*M)) {
            printf("Erreur : impossible de réallouer la mémoire pour M\n");
            exit(EXIT_FAILURE);
        }
        strcpy(*M,tmp);
        free(tmp);
    }

    Une telle fonction serait appelée dans un contexte similaire à :

    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
    int main(void)
    {
        char suite[] = "67890";
     
        char * s1 = malloc(6);
        if (!s1) {
            printf("Erreur : impossible d'allouer la mémoire\n");
            return EXIT_FAILURE;
        }
        strcpy(s1, "12345");
        printf("s1 contient %s\n", s1);
        ModifierCapacite(&s1, suite);
        strcat(s1, suite);
        printf("s1 contient maintenant %s\n", s1);
        free(s1);
     
        return 0;
    }

    C'est une fonction utile, servant à redimensionner une allocation dynamique pour accueillir une nouvelle chaîne dedans. Bien sûr, l'implémentation est maladroite et la fonction standard realloc() devrait être utilisée au lieu de se casser la tête à faire un malloc, une copie, un free, un malloc, une nouvelle copie et de nouveau free.

    J'ai déjà donné un exemple d'usage de realloc() (dans ce post) sans créer de fonction additionnelle.

    Si on veut créer une fonction void ModifierCapacite(char ** M, char * T) que l'on puisse appeler de la même façon que ci-dessus et utilisant en interne realloc(), cela donne quelque chose comme ceci, qui est déjà plus simple :

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void ModifierCapacite(char ** M, char * T)
    {
        char * stmp = NULL;
     
        stmp = realloc(*M, strlen(*M) + strlen(T) + 1);
        if (!stmp) {
            printf("Erreur : impossible de modifier la quantité "
                    "de mémoire allouée\n");
            exit(EXIT_FAILURE);
        }
        *M = stmp;
    }

    En réalité, le double pointeur n'est pas réellement indispensable non plus, et peut être sources d'erreurs dans l'utilisation. On peut rapidement arriver à des pointeurs de pointeurs de pointeurs... pfff. bref, comme d'autres, je ne les aime pas. On devrait faire plus simple pour ne pas augmenter inutilement le niveau d'indirections. Sur le modèle de fonctionnement de realloc(), en passant une simple copie du pointeur à redimensionner en paramètre, et en retournant le pointeur réalloué, on peut faire :

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    char * ModifierCapacite(char * M, char * T)
    {
        char * stmp = NULL;
     
        stmp = realloc(M, strlen(M) + strlen(T) + 1);
     
        return stmp;
    }
    (edit: suppression des lignes 6 et 7 après le realloc if (!stmp) return NULL; car de toutes façons NULL serait retourné avec le return final)

    cette fonction s'utilisant dans main comme suit :

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        char * s1tmp = ModifierCapacite(s1, suite);
        if (!s1tmp) {
            printf("Erreur : impossible de modifier la quantité "
                    "de mémoire allouée\n");
            return EXIT_FAILURE;
        }
        s1 = s1tmp;

    ainsi, la fonction se comporte d'une façon inspirée de realloc(), à la différence que le 2ème paramètre n'est pas la nouvelle taille, mais une chaîne et que la fonction doit utiliser la taille des deux chaînes pour déterminer la nouvelle taille.

    @joujou98 :

    Relis les différentes interventions de ce fil pour bien comprendre ce code et le pourquoi de tes erreurs.

    Vois https://en.cppreference.com/w/c/memory/realloc

    Comme il s'agit de mon code, si tu l'utilises, je te demande de mettre une attribution de copyright dessus "(c) 2018, -Eks- du forum developpez.net" dans ton code source :-P

    .. heu, tout bien réfléchi, non... ton code était bien plus original que le mien ;-)

  18. #18
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par -Eks- Voir le message
    A titre préalable, joujou98 essaye désormais de faire quelque chose de différent de sa question initiale (ce qui pourrait indiquer que le prototype initial n'était pas une exigence d'un énoncé, mais juste un prototype que joujou98 pensait pouvoir utiliser).
    Tu dis ça d'après son dernier code ? D'après un truc qui'l aurait dit dans le topic et que j'aurais pas vu ? Ou bien d'après un truc qu'il t'aurait envoyé en privé ? Parce que moi j'avais pas compris ça.

    Citation Envoyé par -Eks- Voir le message
    Ton exemple montre correctement comment passer l'adresse d'un pointeur sur char, afin que la fonction appelée puisse modifier le contenu de la variable pointeur, qui n'est pas initialisé dans ton cas. Cependant :

    • La fonction ModifierCapacite() que joujou98 essaye de mettre au point sert visiblement à modifier une capacité de stockage déjà allouée
    • La fonction que joujou98 essaye de faire prend 2 paramètres, qui correspondent visiblement à des pointeurs sur char pointant sur quelque chose, sinon elle n'utiliserait pas strlen() dessus et ne ferait pas ce qu'elle essaye de faire, c'est dire copier temporairement le contenu de la zone mémoire pointé par M ailleurs, la libérer, allouer une zone mémoire plus grande et tenter d'y remettre le contenu
    • Ton exemple écraserait une adresse mémoire existante dans M et ne comprendrait pas d'information quant à "de combien il faut augmenter la capacité" ou comment la "modifier"
    • Ton exemple est valide pour une fonction d'allocation, mais alors le nom ModifierCapacite() est inapproprié et autant faire un prototype char * AllouerMemoire(void) qui évite des complications (mais ce n'est pas ce que joujou98 veut faire)
    Mon exemple est un exemple généraliste. J'ai utilisé son nom ModifierCapacite pour qu'il puisse faire l'analogie avec ce qu'il tente de faire et qui a pour base "comment faire modifier un pointeur par une fonction" (qui dérive lui-même de "comment faire modifier une variable par une fonction") mais tout cela nécessite ensuite (et bien évidemment) de sa part
    • un travail d'apprentissage (c'est quoi un pointeur, à quoi ça sert, c'est quoi une chaine, comment lier chaine et pointeur, etc)
    • un travail de compréhension (qu'est-ce qu'il a écrit, comment ça marche, je vais retaper ça de mon côté et faire mes propres essais, rajouter des printf() pour voir ce qui se passe, etc)
    • un travail d'adaptation (ok, lui il alloue un pointeur, moi je veux allouer un pointeur et y copier des trucs qui sont dans un autre)


    Citation Envoyé par -Eks- Voir le message
    Ce topic atteint des proportions dantesques sur des sujets non triviaux (y compris sur des sujets éloignés de la question ou des questions posée(s)), avec des informations dispersées et des interventions elliptiques de certains intervenants.
    Je compatis à la situation de joujou98 qui ne doit pas être évidente (surtout si elle est débutante) et je ne lui ferait pas le procès d'intention de n'avoir "rien lu".
    C'est vrai, tu n'as pas tort. Donc appliquons la règle de base des forums : nouveau problème=nouveau topic. Que joujou98 ouvre un nouveau topic en expliquant ce qu'il tente de faire.
    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]

Discussions similaires

  1. Réponses: 8
    Dernier message: 12/02/2013, 01h08
  2. Réponses: 2
    Dernier message: 18/10/2003, 14h42
  3. Chaînes de caractères
    Par Zazeglu dans le forum C
    Réponses: 3
    Dernier message: 28/08/2003, 16h20
  4. Inverser une chaîne de caractères
    Par DBBB dans le forum Assembleur
    Réponses: 2
    Dernier message: 30/03/2003, 11h09
  5. Réponses: 3
    Dernier message: 09/05/2002, 01h39

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