Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[débutant] (string +(nombre->string) -> * char

2 réponses
Avatar
Cyrcocq
Bonjour,

J'ai besoin d'un pointeur * char (pas constant)
Je voudrais qu'il pointe vers un texte suivi par le résultat d'un calcul.

J'ai donc fait

int fps;
...
ostringstream oss;

oss << "la perf est de "<< fps << "fps" <<endl;

string titre = oss.str();

const char *c_titre = titre.c_str ( );

Et j'ai obtenu un pointeur vers une chaine constante...

Mais la fonction qui en a besoin veut un char * tout court.

Alors... heu...

Je remplace ma derniére ligne par

size_t size = titre.size() + 1;
char * c_titre = new char[size];

strncpy( c_titre, titre.c_str(), size );
....

delete [ ] c_titre;



C'est ça l'idée?

Ou est ce qu'il y a mieux (plus rapide à executer? Parce q'en fait c'est lié
à un test de perf en frames par secondes...)

2 réponses

Avatar
Fabien LE LEZ
On Mon, 5 Sep 2005 23:49:29 +0200, "Cyrcocq" :

const char *c_titre = titre.c_str ( );

Et j'ai obtenu un pointeur vers une chaine constante...

Mais la fonction qui en a besoin veut un char * tout court.


Dans ce cas, il faut passer par un std::vector<char> (Je dis "il faut"
car je ne connais pas d'autre méthode).

std::vector<char> buf
// remplissage
"&buf[0]" est ton "char*"
buf.size() est la taille totale du buffer.

Dans ton cas, étant donné qu'il faut un char* terminé par un ''
(enfin, je suppose), je te propose deux solutions :

Solution 1 :

std::vector<char> buf (c_titre.begin(), c_titre.end());
buf.push_back ('');
la_fonction_en_question (&buf[0]);

Solution 2 :

std::vector<char> buf (c_titre.c_str(), c_titre.size()+1);
la_fonction_en_question (&buf[0]);


Il y a une troisième solution, qu'on peut parfois utiliser en
désespoir de cause, si on sait vraiment ce qu'on fait.
Supposons une fonction "foo (char* bar)", dont la documentation
affirme qu'elle ne modifie jamais son argument. En d'autres termes,
son prototype est mal fait, il aurait dû être "foo (char const* bar)".
Dans ce cas, et dans ce cas seulement, tu peux l'encapsuler ainsi :

void foo (char const* bar)
{
foo (const_cast<char*>(bar));
}

Bien évidemment, ici, cette solution ne s'applique pas, puisqu'il est
beaucoup plus simple de copier la chaîne dans un tableau non-const.

Avatar
kanze
Cyrcocq wrote:

J'ai besoin d'un pointeur * char (pas constant) Je voudrais
qu'il pointe vers un texte suivi par le résultat d'un calcul.

J'ai donc fait

int fps;
...
ostringstream oss;

oss << "la perf est de "<< fps << "fps" <<endl;

string titre = oss.str();

const char *c_titre = titre.c_str ( );

Et j'ai obtenu un pointeur vers une chaine constante...

Mais la fonction qui en a besoin veut un char * tout court.


Pourquoi ? Si ce n'est que parce que c'est une fonction
ancienne, qui ne connaît pas le const, mais qui ne modifie pas
la chaîne, const_cast doit suffit. (Ça me semble probable, si la
fonction veut une chaîne déjà formattée en entrée.) Si en
revanche la fonction va réelement modifier la chaîne, il faut
bien passer par un buffer intermediare, gerer par std::vector ou
boost::array_ptr.

Alors... heu...

Je remplace ma derniére ligne par

size_t size = titre.size() + 1;
char * c_titre = new char[size];

strncpy( c_titre, titre.c_str(), size );
....

delete [ ] c_titre;

C'est ça l'idée?


Un peu. J'aurais écrit plutôt :

std::vector< char > v( titre.begin(), titre.end() ) ;
v.push_back( '' ) ;
// utiliser &v[ 0 ]

Mais c'est probablement surtout une question de style. (Ce que
j'ai écrit est « exception safe ». Mais s'il s'agit de
simplement appeler une fonction qui prend un char*, il y a peu
de risque que cette fonction lève une exception.)

Ou est ce qu'il y a mieux (plus rapide à executer? Parce q'en
fait c'est lié à un test de perf en frames par secondes...)


D'abord et avant tout, vérifier si tu pourrais simplement te
servir du const_cast. D'après la contexte que tu donnes ici,
c'est fort probable. Sinon, essayer d'établir une taille maximum
du buffer avant de le formatter, de façon statique. Puis,
quelque chose du genre :

char buffer[ tailleMax ] ;
ostrstream oss( buffer, tailleMax ) ;
oss << "la perf est de " << fps << "fpsn" << ends ;
functionX( buffer ) ;

Ensuite, mais seulement si vraiment le code ci-dessus n'est pas
assez rapide, tu pourrais même écrire ton propre streambuf, pour
être plus rapide (parce que moins d'options à tester). Dans ce
cas précis, le streambuf peut s'écrire en moins d'une dizaine de
lignes. De même, si fps est un entier, une conversion sur
mesure, sans options à tester, irait un peu plus vite que la
conversion standard. Mais ce sont des mesures extrèmes.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34