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

Réseau C Discussion :

[newbie]chaine de caracteres en parametres


Sujet :

Réseau C

  1. #21
    Expert confirmé
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 4 062
    Points
    4 062
    Par défaut
    Ah c'était ça le probleme!

    Euh! en fait j'ai merdé:j'avais fait des test avec malloc AVANT,qui ne marchaient pas.

    Le malloc est un "reste" des tests précédents et evidemment il ne sert à rien.

    La prochaine fois j'y regarderai à deux fois.

    Désolé pour ce malentendu.
    EDIT :
    Absurde. Le bloc alloué est perdu. Rester simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       char *chaine = "Bonjour";
    est bien ce qu'il faut lire.
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  2. #22
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    Cette solution est elle donc correcte ?

    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
     
    #include <stdio.h>
     
    void test(char **chaine, int *a)
    {
       *a = 0;
       *chaine = "salut";
       printf("chaine: %s, a: %i\n", *chaine, *a);
    }
     
    int main(int argc, char *argv[])
    {
       char *chaine;
       int a = 10;
     
       chaine = "Bonjour";
       printf("chaine: %s, a: %i\n", chaine, a);
       test(&chaine, &a);
       printf("chaine: %s, a: %i\n", chaine, a);
    }
    Je veux en effet modifier le contenu de la zone memoire pointee par chaine dans le main.

  3. #23
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Tex-Twil
    Cette solution est elle donc correcte ?
    Ce code est correct ...
    Je veux en effet modifier le contenu de la zone memoire pointee par
    chaine dans le main.
    ... mais il ne fait pas ce que tu veux. En effet, il se contente de faire pointer 'chaine' ailleurs (c'est la valeur du pointeur 'chaine' qui a été modifiée)

    Si tu veux modifier le valeur pointée par chaine, il faut que celle-ci soit modifiable (tableau de char):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       char chaine[] = "Bonjour";
    et, pour avoir les moyens d'éviter les catastrophes, passer à la fonction, non seulement l'adresse du premier élément du tableau, mais aussi son nombre d'élements.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       test(chaine, sizeof chaine);
    Le prototype est donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       void test(char *chaine, size_t size);
    Je te laisse écrire le code...
    Pas de Wi-Fi à la maison : CPL

  4. #24
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Ce code est correct ...
    ... mais il ne fait pas ce que tu veux. En effet, il se contente de faire pointer 'chaine' ailleurs (c'est la valeur du pointeur 'chaine' qui a été modifiée)
    Bon En fait, je veux recuperer Salut dans mon main. Peu importe la si c'est une autre zone memoire.

    Si j'ai bien compris:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    char *chaine;
    chaine = "Bonjour";
    chaine = "ca va ?";
    Ce code fait dabord pointer chaine vers la zone contenant "Bonjour" et puis vers la zone contentant "ca va ?"

    EDIT: non ce n 'est pas ca.
    EDIT2: je suis perdu je pense au il me faudrait un dessin
    EDIT3:
    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
     
    #include <stdio.h>
     
    void test(char **chaine)
    {
    	// contenu de chaine
    	*chaine = "salut";
    	// contenu de la chaine et adresse du contenu
    	printf("chaine: %s, son adresse: %x\n", *chaine, &*chaine);
    }
     
    int main(int argc, char *argv[])
    {
       char *chaine;
     
       chaine = "Bonjour";
       printf("chaine: %s, son adresse: %x\n", chaine, &chaine);
       chaine = "ca va ?";   
       printf("chaine: %s, son adresse: %x\n", chaine, &chaine);  
       test(&chaine);
       printf("chaine: %s, son adresse: %x\n", chaine, &chaine);
    }
    Il s'agit bien de la meme zone memoire ici.

  5. #25
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Tex-Twil
    Bon En fait, je veux recuperer Salut dans mon main. Peu importe la si c'est une autre zone memoire.
    Si j'ai bien compris:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    char *chaine;
    chaine = "Bonjour";
    chaine = "ca va ?";
    Ce code fait dabord pointer chaine vers la zone contenant "Bonjour" et puis vers la zone contentant "ca va ?"
    Oui, tu as bien compris.
    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
     
    #include <stdio.h>
     
    void test(char **chaine)
    {
    	// contenu de chaine
    	*chaine = "salut";
    	// contenu de la chaine et adresse du contenu
    	printf("chaine: %s, son adresse: %x\n", *chaine, &*chaine);
    }
     
    int main(int argc, char *argv[])
    {
       char *chaine;
     
       chaine = "Bonjour";
       printf("chaine: %s, son adresse: %x\n", chaine, &chaine);
       chaine = "ca va ?";   
       printf("chaine: %s, son adresse: %x\n", chaine, &chaine);  
       test(&chaine);
       printf("chaine: %s, son adresse: %x\n", chaine, &chaine);
    }
    Il s'agit bien de la meme zone memoire ici.
    Ca revient à faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
       char *chaine;
     
       chaine = "Bonjour";
       chaine = "salut";
       chaine = "ca va ?";   
       chaine = "salut";
    A chaque fois, c'est la valeur du pointeur qui change et va pointer vers différentes chaines fixes.
    Pas de Wi-Fi à la maison : CPL

  6. #26
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    ok, je vois.

    Maintenant qu'en est il de l'allocation de la memoire ? faut il le faire.

  7. #27
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Tex-Twil
    Maintenant qu'en est il de l'allocation de la memoire ? faut il le faire.
    Uniquement si tu veux faire une copie de la chaine...
    • Déterminer la taille
    • Allouer le bloc
    • Faire la copie
    • Quand on a plus besoin de la copie, libérer le bloc (free()).
    Pas de Wi-Fi à la maison : CPL

  8. #28
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    ok.
    maintenant compliquons les choses

    J'ai besoin d'ecrire cette chaine dans un socket.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ...
    //server's public key
    char *s_pub_key;
    generateDH(PRIME, GENERATOR, &s_pub_key);
    // client connected
    send(client_sock, s_pub_key, strlen(s_pub_key), 0);
    ceci a l'air de marcher mais est-ce correcte ?

  9. #29
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par Tex-Twil
    ok.
    maintenant compliquons les choses

    J'ai besoin d'ecrire cette chaine dans un socket.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ...
    //server's public key
    char *s_pub_key;
    generateDH(PRIME, GENERATOR, &s_pub_key);
    // client connected
    send(client_sock, s_pub_key, strlen(s_pub_key), 0);
    ceci a l'air de marcher mais est-ce correcte ?
    Je mettrais:
    send(client_sock, s_pub_key, strlen(s_pub_key)+1, 0);

    Pour envoyer le '\0' de la chaîne mais ce n'est pas obligatoire. Par contre, cela évite de devoir le mettre à la réception.

    Jc

  10. #30
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    ok mais il y a toujours un truc qui me tracasse :

    Citation Envoyé par DVP.net
    La dernière méthode (char *s3 = "Developpez";) ne réserve pas de mémoire, elle se contente de stocker l'adresse d'une chaîne de caractères qui peut se trouver dans un endroit de la mémoire non modifiable par le programme, dans ce cas toute modification de la chaîne s3 se conclura par une erreur de segmentation
    Ca veut dire que dans le code suivant la 3eme instruction peut echouer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      char *chaine;
     
       chaine = "Bonjour";
       chaine = "salut";                  <---------------- Celle la
       chaine = "ca va ?";   
       chaine = "salut";

  11. #31
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Tex-Twil
    Ca veut dire que dans le code suivant la 3eme instruction peut echouer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      char *chaine;
     
       chaine = "Bonjour";
       chaine = "salut";                  <---------------- Celle la
       chaine = "ca va ?";   
       chaine = "salut";
    Non. Aucun problème avec ce code. Tu as le droit de faire pointer un pointeur où tu veux, du moment que c'est le même type.
    Pas de Wi-Fi à la maison : CPL

  12. #32
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par Tex-Twil
    ok mais il y a toujours un truc qui me tracasse :

    Citation Envoyé par DVP.net
    La dernière méthode (char *s3 = "Developpez" ne réserve pas de mémoire, elle se contente de stocker l'adresse d'une chaîne de caractères qui peut se trouver dans un endroit de la mémoire non modifiable par le programme, dans ce cas toute modification de la chaîne s3 se conclura par une erreur de segmentation
    Ca veut dire que dans le code suivant la 3eme instruction peut echouer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      char *chaine;
     
       chaine = "Bonjour";
       chaine = "salut";                  <---------------- Celle la
       chaine = "ca va ?";   
       chaine = "salut";
    Non puisque tu ne modifies pas la chaînes, tu modifies la valeur d'un pointeur. La zone pointée peut être une zone modifiable ou non, d'où le problème.

    Par contre tu n'as pas le droit (enfin si, mais à tes risques et périls) de faire ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    chaine = "salut";
    chaine[0] = 'B';
    Ceci est un problème qui peut être éviter en utilisant le warning: -Wwrite-strings

    Jc

  13. #33
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    ok. enfin derniere chose.

    J'aimerais recuperer cette chaine de lautre cote du socket comme ceci. (On devie un peu du sujet)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    char buff[MAXDATASIZE];
    if( (numbytes = recv(sock, pub_key, MAXDATASIZE-1, 0)) == -1 )
    {
    	perror("recv");
    	exit(2);
    }
    Ainsi buff contient la chaine (y compris le \0) mais j aimerais recuperer tout ca sous forme char *ma_chaine Non pas un tableau.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char *machaine;
    machaine = buff
    ?

  14. #34
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    en dautres termes comment copier un
    char ma_chaine1[1024]
    vers
    char *ma_chaine2;

  15. #35
    Membre averti Avatar de Jack_serious
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 350
    Points : 396
    Points
    396
    Par défaut
    Citation Envoyé par Tex-Twil
    en dautres termes comment copier un
    char ma_chaine1[1024]
    vers
    char *ma_chaine2;
    En allouant assez d'espace dans ma_chaine2 et en faisant une copie de ma_chaine1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include <stdlib.h>
    #include <string.h>
     
    ma_chaine2 = malloc((strlen(ma_chaine1) + 1) * sizeof(*ma_chaine2));
    if (ma_chaine2 == NULL)
         /* Traitement de l'erreur */
    else
    {
      memcpy(ma_chaine2, ma_chaine1, strlen(ma_chaine1) + 1); /* Le +1 sert a copier egalement le '\0' pour eviter de le faire apres... */
    }
    Don't worry, be serious.
    La vie est courte. Prenez votre temps.

    Jack.

  16. #36
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    Citation Envoyé par Jack_serious
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ma_chaine2 = malloc((strlen(ma_chaine1) + 1) * sizeof(*ma_chaine2));
    Je ne comprends pas la taille de la memoire. pourquoi * sizeof(*ma_chaine2)

  17. #37
    Membre averti Avatar de Jack_serious
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 350
    Points : 396
    Points
    396
    Par défaut
    Citation Envoyé par Tex-Twil
    Citation Envoyé par Jack_serious
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ma_chaine2 = malloc((strlen(ma_chaine1) + 1) * sizeof(*ma_chaine2));
    Je ne comprends pas la taille de la memoire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    strlen(ma_chaine1)           /* => longueur de la chaine */
    +1                                          /* => pour contenir le '\0' puisque qu'il n'est pas compte par strlen()
    * sizeof(*ma_chaine2)      /* => correspond a la taille d'un caractere
    Avec ce code tu alloues : (longueur_de_la_chaine + 1) * taille_d_un_caractere.
    Don't worry, be serious.
    La vie est courte. Prenez votre temps.

    Jack.

  18. #38
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    ok,
    utiliser sizeof(char) convient aussi j'imagine.

  19. #39
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Tex-Twil
    utiliser sizeof(char) convient aussi j'imagine.
    Tant que le type est char... Si il devient wchar_t (pour unicode, par exemple), il faut modifier le code...

    C'est pourquoi il recommandé d'utiliser la forme générale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       T *p = malloc (sizeof *p * n);
    Qui fonctionne quelque soit le type T (sauf void, évidemment), et qui réduit la maintenance au minimum.
    Pas de Wi-Fi à la maison : CPL

  20. #40
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    c"est normal que le code danc ce topic s'affiche n'importe comment ???

Discussions similaires

  1. Réponses: 2
    Dernier message: 06/11/2011, 11h30
  2. Réponses: 9
    Dernier message: 06/11/2007, 12h36
  3. Pb Update avec chaine de caractere
    Par JuJu° dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 28/05/2003, 15h58
  4. [LG]comparaison de chaines de caracteres
    Par thesam dans le forum Langage
    Réponses: 6
    Dernier message: 20/05/2003, 22h41
  5. Probleme sur les chaines de caractere
    Par scorpiwolf dans le forum C
    Réponses: 8
    Dernier message: 06/05/2002, 19h01

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