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 :

sprintf dans une fonction


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Octobre 2010
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Octobre 2010
    Messages : 15
    Par défaut sprintf dans une fonction
    Bonjour,

    j'ai un problème qui va sans doute vous paraître tout bête mais je n'ai pas trouvé la réponse dans la FAQ.

    Je veux afficher un "hello world". J'ai une chaîne initiale qui contient "hello" et je veux lui ajouter "world" à la fin via un sprintf dans une fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void afficherHello(char *chaine[100])
    {
        sprintf(*chaine, "%s world", *chaine);
    }
     
    char *chaine = "Hello";
    afficherHello(&chaine);
    Avec ce code, la compilation réussit mais le programme plante. Quel est le problème ? Je pense qu'il y a un souci au niveau des pointeurs, mais lequel ?

    Merci d'avance.

  2. #2
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    les paramètres de la procédure que tu déclare n'ont rien à voir avec ceux que tu veux passer.

    ici tu indique un tableau de 100 pointeur sur char
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void afficherHello(char *chaine[100])
    là tu définit un char * contenant 5 caractères.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char *chaine = "Hello";
    si tu utilise gcc comme compilateur tu peux activer les flags de compilations suivants:
    -Wall (active tous les principaux warning de compilation)
    -Wextra (ajoute des warning supplémentaires)
    -Werror (traite les warning comme des erreurs, bloque la compilation)

    Ceci me parait mieux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <stdio.h>
     
    void afficherHello(char  s[100]) {
      sprintf(s,"%s world",s);
    }
     
    int main() {
      char hello[100] = {'h','e','l','l','o',0};
      afficherHello(hello);
      printf("--> %s",hello);
      return 0;
    }

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

    En écrivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *chaine = "Hello";
    Tu n'alloues pas de mémoire pour la variable "chaine", elle pointe juste une chaine constante.

    Une bonne pratique pour ce que tu veux faire est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void ajouterWorld(char *chaine)
    {
        strcat(chaine, " world");
    }
     
    void test (void) {
        char chaine[256] = "Hello";
        ajouterWorld(chaine);
        printf(chaine);
    }

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Ce que tu veux faire, avec ton exemple n'est pas possible.

    Tu essaye d'ajouter quelque chose à la fin d'une chaine de caractères constantes allouée par le compilateur, tu n'as pas le droit d'y toucher, ce n'est pas ta chaine.

    Il faut passer par une chaine de caractères qui t'appartient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int main(()
    {
    char chaine[256];
       strcpy(chaine, "Hello");
       afficherHello(chaine);
    }
     
    void afficherHello(char *chaine)
    {
        sprintf(&chaine[strlen(chaine)], " world");
    }
    Toujours dans ton exemple, strcat() est probablement plus efficace que sprintf()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void afficherHello(char *chaine)
    {
       strcat(chaine, " world");
    }
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre averti
    Inscrit en
    Octobre 2010
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Octobre 2010
    Messages : 15
    Par défaut
    Merci pour ces réponses rapides !

    Vos codes fonctionnent mais j'avoue ne pas comprendre exactement pourquoi. Comment le code de Jabbounet marche-t-il sans faire appel aux pointeurs ? Pour faire la même chose avec une variable numérique on a besoin des pointeurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void incrementer(int *nombre)
    {
        *nombre++;
    }
     
    int nombreAIncrementer = 5;
    incrementer(&nombreAIncrementer);
    Pourquoi ne peut-on pas procéder de la même façon pour les chaînes ?

  6. #6
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par Nadawoo Voir le message
    Pourquoi ne peut-on pas procéder de la même façon pour les chaînes ?
    Lis ce post : Question : L'adresse du pointeur sur un tableau, tu comprendras peut être mieux la subtilité de la chose.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  7. #7
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Comment le code de Jabbounet marche-t-il sans faire appel aux pointeurs ?
    Cela marche car je déclare un tableau de 100 char que j'initialise directement avec la valeur "hello\0", au lieu de déclarer un pointeur sur une chaine constante.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     char hello[100] = {'h','e','l','l','o',0};
    En écrivant par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     char *hello = "hello";
     hello[0]='H';
    A l'exécution, il y'a segmentation fault car le programme essaie de modifier "hello" qui est une constante du point de vue du compilateur.

    Alors que le code suivant marchera, le tableau est alloué sur la pile, et sa valeur est initialisé en recopiant le contenu de la chaine {'h','e','l','l','o',0} dedans.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char hello[100] = {'h','e','l','l','o',0};
    hello[0]='H';
    Ensuite, tant que le tableau passé en paramètre contiens suffisamment de place pour insérer " world\0" à la fin cela marchera ("hello world\0" fait 12 caractères), sinon .....
    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
     
    #include <stdio.h>
    #include <string.h>
     
     
    void afficherHello(char  s[100]) {
      printf("-->        %5d %s\n", strlen(s),s);
      sprintf(s,"%s world",s);
    }
     
    int main() {
      int i = 0;
      char hello[12] = {'h','e','l','l','o',0}; /* tableau trop petit */
      for(i = 0; i < 100 ; i++) {
        afficherHello(hello);
        printf("--> %5d  %5d %s\n",i, strlen(hello),hello);
      }
      return 0;
    }
    Me donne à l'exécution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    -->            5 hello
    -->     0     11 hello world
    -->           11 hello world
    -->     1     17 hello world world
    -->           17 hello world world
    -->     2     23 hello world world world
    -->           23 hello world world world
    -->   100     29 hello world world world world
    au lieu d'avoir une boucle de 0 à 100

  8. #8
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par jabbounet Voir le message
    Cela marche car je déclare un tableau de 100 char que j'initialise directement avec la valeur "hello\0", au lieu de déclarer un pointeur sur une chaine constante.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     char hello[100] = {'h','e','l','l','o',0};
    Note que char hello[100] = "hello"; fonctionnerait tout aussi bien.

  9. #9
    Membre averti
    Inscrit en
    Octobre 2010
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Octobre 2010
    Messages : 15
    Par défaut
    Ah OK, je pense avoir à peu près compris. J'ai un peu de mal avec les pointeurs.

  10. #10
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Petit truc amusant pour aller plus loin.

    tu ne peux pas modifier la contante sur laquelle pointe hello dans ce cas, mais rien ne t'empêche de modifier le pointeur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdio.h>
     
    int main() {
      char *hello = "hello";
      while (*hello != 0) {
        printf(" %p - %c -\n",hello, *hello);
        hello++;
      }
      printf("fin\n");
      return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     0x40201c - h -
     0x40201d - e -
     0x40201e - l -
     0x40201f - l -
     0x402020 - o -
    fin

Discussions similaires

  1. Recuperation de formulaire dans une fonction
    Par arsgunner dans le forum ASP
    Réponses: 5
    Dernier message: 23/06/2004, 15h04
  2. Transmission d'un objet crée dans une fonction
    Par EvilAngel dans le forum ASP
    Réponses: 2
    Dernier message: 10/05/2004, 20h19
  3. Utilisez MinimizeName() dans une fonction
    Par James_ dans le forum C++Builder
    Réponses: 7
    Dernier message: 07/05/2004, 18h05
  4. [Postgresql]Connecter à une autre base dans une fonction
    Par alex2205 dans le forum Requêtes
    Réponses: 2
    Dernier message: 05/05/2003, 11h30
  5. [Turbo Pascal] Allocation et désallocation de pointeurs dans une fonction
    Par neird dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 17/11/2002, 20h14

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