Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2656 connectés 

  FORUM HardWare.fr
  Programmation
  C

  printf("%s") sur fonction renvoyant une chaîne [RESOLU]

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

printf("%s") sur fonction renvoyant une chaîne [RESOLU]

n°1051762
Sve@r
Posté le 19-04-2005 à 09:24:42  profilanswer
 

Bonjour,
j'ai un soucis pour écrire une fonction renvoyant une chaîne.
Voici un résumé simplifié du problème

char *str(int n)
{
    static char ret[2];
    ret[0]=n + '0';
    ret[1]='\0';
    return(ret);
}


En fait, la fonction est plus complexe que transformer un simple nombre d'un caractère en numérique ascii mais c'est seulement pour résumer le soucis et les tests que j'ai fait pour trouver où se situait le problème
 
Donc, si je l'appelle de cette façon

int main(void)
{
    printf("%c %c\n", *str(2), *str(3));
}


Juste pour vérifier => ok => j'ai "2 3" à l'écran
 
Maintenanjt, si je l'appelle de cette façon

int main(void)
{
    printf("%s %s\n", str(2), str(3));
}


Petit ennui, j'ai "2 2" à l'écran
 
J'ai inclus des traceurs dans la fonction à coup de "fputc" et je relève que "str(3)" est appelé avant "str(2)". J'ai aussi essayé "printf("%d %d\n", i++, i++)" qui montre aussi que les arguments sont évalués dans l'ordre inverse.
Je ne connais pas le fonctionnement intrinsèque de "printf" mais j'en ai déduis qu'il devait probablement mémoriser les pointeurs renvoyés par la fonction. Mais comme ma fonction renvoie le même pointeur à chaque fois je n'obtiens pas ce que je voudrais.
 
Comment contourner le problème ? Mettre un "malloc" m'obligera à mémoriser le pointeur pour le libérer. Ne pas le mettre en "static" ne me le protègera plus d'un écrasement éventuel. Si qqun a une solution intéressante à proposer je prends...
 
Merci


Message édité par Sve@r le 20-04-2005 à 08:04:52

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
mood
Publicité
Posté le 19-04-2005 à 09:24:42  profilanswer
 

n°1051837
Sve@r
Posté le 19-04-2005 à 10:20:35  profilanswer
 

Sve@r a écrit :

Comment contourner le problème ?


 
Ben en fait j'ai trouvé une solution assez satisfaisante que je vous propose ici:
J'ai modifié la fonction et son appel de cette façon:

char *str(int n, unsigned short appel)
{
    static char ret[1024][2];
    ret[appel][0]=n + '0';
    ret[appel][1]='\0';
    return(ret[appel]);
}
 
int main(void)
{
    printf("%s %s\n", str(2, 0), str(3, 1));
}


 
Mantenant si qqun a mieux...
 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1051842
Taz
bisounours-codeur
Posté le 19-04-2005 à 10:22:40  profilanswer
 

beurk !
 
utilise snprintf
 

Code :
  1. char buf[80];
  2. snprintf(buf, sizeof buf, "%d %d", 1, 2);

n°1051883
Taz
bisounours-codeur
Posté le 19-04-2005 à 10:44:14  profilanswer
 

Sve@r a écrit :

Ben en fait j'ai trouvé une solution assez satisfaisante que je vous propose ici


ah oui au fait, revois un peu tes exigences, parce que moi ta fonction, je la qualifie de pourrie et gravement bugguée

n°1051918
Tarabiscot​e
Posté le 19-04-2005 à 11:07:22  profilanswer
 

En supposant que snprintf ne correspond pas à ce qu'il veut faire.
 
Pourquoi ne pas utiliser de structure ?
 

typedef struct
{
  char val[2];
} string;
 
string str(int n)
{
    string ret;
    ret.val[0]=n + '0';
    ret.val[1]='\0';
    return ret;
}
 
int main(int argc, char *argv[])
{
  string s1 = str(2);
  string s2 = str(3);
  printf("%s %s\n", s1.val, s2.val);
}

n°1051933
Taz
bisounours-codeur
Posté le 19-04-2005 à 11:17:57  profilanswer
 

oui c'est aussi une bonne solution. ou de procéder par allocation dynamique ça peut servir aussi. Mais bon, c'est du réinventage de roue.

n°1052783
Emmanuel D​elahaye
C is a sharp tool
Posté le 19-04-2005 à 20:08:45  profilanswer
 

Sve@r a écrit :

j'ai un soucis pour écrire une fonction renvoyant une chaîne.
Voici un résumé simplifié du problème

char *str(int n)
{
    static char ret[2];
    ret[0]=n + '0';
    ret[1]='\0';
    return(ret);
}




Ca marchouille, mais cest pas réentrant (ressource unique). De nombreux effets bizarres sont possibles si il y a des appels imbriqués ou concurrents...

Citation :


En fait, la fonction est plus complexe que transformer un simple nombre d'un caractère en numérique ascii mais c'est seulement pour résumer le soucis et les tests que j'ai fait pour trouver où se situait le problème


Divide & Conquer Strategy. Très efficace...

Citation :


Donc, si je l'appelle de cette façon

int main(void)
{
    printf("%c %c\n", *str(2), *str(3));
}


Juste pour vérifier => ok => j'ai "2 3" à l'écran
 
Maintenanjt, si je l'appelle de cette façon

int main(void)
{
    printf("%s %s\n", str(2), str(3));
}


Petit ennui, j'ai "2 2" à l'écran


Voilà exactement le genre d'effet bizarre dont je parlais...

Citation :


Comment contourner le problème ? Mettre un "malloc" m'obligera à mémoriser le pointeur pour le libérer.


C'est une solution courante. Sinon, passer l'adresse et la taille d'une chaine de destination (comme fait fgets(), par exemple).


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1052950
Sve@r
Posté le 19-04-2005 à 22:49:37  profilanswer
 

Taz a écrit :

beurk !
 
utilise snprintf
 

Code :
  1. char buf[80];
  2. snprintf(buf, sizeof buf, "%d %d", 1, 2);



Bravo, moi je dis bravo. J'ai indiqué que je donnais ici un ersatz simplifié de ma fonction pour illustrer le noeud du problème et tu me réponds "ta fonction est très simple, je peux m'en passer" ! Evidemment !!! Pfff...
 

Taz a écrit :

ah oui au fait, revois un peu tes exigences, parce que moi ta fonction, je la qualifie de pourrie et gravement bugguée


Taz, cher ami, je reconnais bien là ton élégance naturelle alliée à ta vivacité d'esprit qui parait, quand on te lit, tellement aisée...
Vois-tu, certaines personnes arrivées au bout de leurs arguments, se mettent à utiliser des propos grossiers, voire orduriers. Ils espèrent ainsi provoquer chez leur interlocuteur une émotion, émotion provoquée non pas par la justesse de leur raisonnement et la profondeur de leur propos mais simplement par l'impact grossier du mot employé masquant ainsi leur manque flagrant de vocabulaire.
Malheureusement, cette technique possède l'inconvénient majeur de devenir très vite obsolète, l'impact espéré étant rapidement anéanti par la quantité des mots employés. Ainsi moi qui te vois depuis assez longtemps papillonner de ci, de là dans le forum... t'incrustant dans un topic et lui infligeant d'une ligne une sentence bien marquée, je ne suis aujourd'hui plus du tout impressionné par tes remarques n'allant jamais plus haut que le niveau de ton immaturité.
Alors si tu n'as pas plus intéressant à dire que "gravement buggé" et que tu as la flemme ou l'inculture de développer plus en détail, il vaut mieux que tu retournes jouer à Warcraft. Cela m'évitera l'ennui d'avoir à lire les réponses que tu n'as pas fournies.
 

Tarabiscote a écrit :

Pourquoi ne pas utiliser de structure ?

Code :
  1. string str(int n)
  2. {
  3.     string ret;
  4.     ret.val[0]=n + '0';
  5.     ret.val[1]='\0';
  6.     return ret;
  7. }



C'est intéressant mais l'ensemble complet de la structure est renvoyé par recopie (optimisation...). Et je suis obligé de déclarer dans mon main deux structures destinées à recevoir le retour des deux appels à ma fonction => je perds l'avantage que j'espérais à appeler directement ma fonction dans le "printf" comme on peut le faire quand on écrit "printf("%d %d\n", i, fct(i))"
 

Emmanuel Delahaye a écrit :

Ca marchouille, mais c'est pas réentrant (ressource unique). De nombreux effets bizarres sont possibles si il y a des appels imbriqués ou concurrents...
...
Voilà exactement le genre d'effet bizarre dont je parlais...


lol - On retrouve aussi ces effets dans mon "printf("%d %d\n", i++, i++)"
 

Emmanuel Delahaye a écrit :

Sinon, passer l'adresse et la taille d'une chaine de destination (comme fait fgets(), par exemple).


Hmmm... on peut effectivement s'en sortir en plusieurs étapes. Mais j'espérais pouvoir utiliser le mécanisme de l'appel imbriqué justement pour éviter ces étapes. Surtout que mon problème se situe en C++ et que ma fonction "affich" est une méthode d'un de mes objets. Ca m'arrangeait bien de définir mes objets "a" et "b" et de faire un "printf("%s %s\n", a.affich(), b.affich())"
 
Merci de vos réponses. Au-moins j'ai pu donner un exemple concret d'un problème de C pas évident à remonter...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1052970
Taz
bisounours-codeur
Posté le 19-04-2005 à 23:09:06  profilanswer
 

si c'est du C++, utilise std::string, n'utilise pas std::printf et on en parlera plus.

n°1052971
Mackila
Posté le 19-04-2005 à 23:09:36  profilanswer
 

Bah si ton problème est en C++, et que tu dois renvoyer un pointeur, bah ya des trucs dans la STL et dans boost qui te gèrent la vie de ton objet pointé automatiquement... ( boost::auto_ptr ou kekchose du genre)

mood
Publicité
Posté le 19-04-2005 à 23:09:36  profilanswer
 

n°1052981
Taz
bisounours-codeur
Posté le 19-04-2005 à 23:22:29  profilanswer
 

Oh Mon Dieu :/

n°1052982
Joel F
Real men use unique_ptr
Posté le 19-04-2005 à 23:23:57  profilanswer
 

[:totoz]


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  printf("%s") sur fonction renvoyant une chaîne [RESOLU]

 

Sujets relatifs
[résolu] VB.NET ...Quel est ce langage ? -- RESOLU --
[php/js] recuperer une variable js dans une popup -=resolu=-une fonction PHP incroyable. ecrire un fichier avec une var. et zipper
comment ecrire une fonction pour......lecture/écriture binaire (depuis URL) [Résolu]
[JAVA]Pb retour variable... [Résolu][resolu][MYSQL] CREATE VIEW ???
[Débutant] Probeme avec la fonction Curdir ![C] Stocker une valeur entière dans un char * [Résolu]
Plus de sujets relatifs à : printf("%s") sur fonction renvoyant une chaîne [RESOLU]


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR