J'ai Ce code qui fonctionne comme prévu: si je "D Aimez stocker le résultat à un mais j'ai toujours essayer de simplement utiliser i obtenir char * code> (car certaines fonctions dans un cadre que j'utilise utilise uniquement
char * code> comme entrée) sans utiliser le
Strcpy Code> (pour la praticité et la lisibilité du code, et apprendre aussi), comment pourrais-je faire? Garder dans
const code>, cela fonctionne bien: p>
const code>. p>
char * code>: p>
conversion invalide de "const char *" à 'Char *' code>. Quelle est la meilleure habitude pour ce type de conversion? P> P>
4 Réponses :
en C ++, la manière typique de "goutte ceci est, de cours, fronça les sourcils, laids, moche et potentiellement dangereux, car il est vraiment possible que Une solution de contournement consiste à utiliser un ce ne sera bien sûr bien sûr que si const code>" est en utilisant
const_cast <> code>:
getname () code> renvoie un pointeur sur quelque chose que ne devrait pas être changé em>, puis vous allez donner vous-même la permission de le changer. C'est un bon moyen de devenir très difficile de trouver des bugs, dans ce cas. P>
std :: string code> comme zone de détention temporaire; Il signifiera la copie de la chaîne mais qui pourrait être acceptable de performance-wise: p>
nom code> n'est pas conservé Lorsque
s code> est hors de portée. Si tel est le cas, vous allez avoir une forme de couche de stockage de chaîne persistante. P> p>
Retirer Const d'un Const Const * code> comportement non défini?
Si je peux demander, pourquoi suggérez-vous quelque chose qui est froncé sur, sans donner d'autres suggestions?
@Default Parce que c'était ce que l'affiche voulait savoir comment faire, et je ne saurais savoir pour certains que ce soit mauvais dans la situation en question.
.c_str () code> est const.
Char * Nom = s.c_str (); code> n'est pas compilable.
@Default Supprimer const n'est pas UB. Mais vous êtes correct que std :: string :: c_str code> ne fonctionne pas car il retourne
const char * code>.
Attention à modifier les caractères dans un littéral de chaîne C ++ est UB. Ils sont généralement stockés dans une section de mémoire en lecture seule. Casting Le const ne provoquera pas le problème, mais une tentative ultérieure d'écrire dans cette région de mémoire sera. Ne suggère pas de telles choses; Le seul moyen de créer correctement une chaîne mutable d'un littéral de chaîne C ++ est de le copier.
Si vous utilisez un fonction qui prend un sinon, vous risquez un comportement non défini à l'exécution si une fonction tente de modifier une chaîne en lecture seule. P> Ce que vous avez actuellement est adéquat; En supposant que vous ne puissiez pas travailler avec Enfin, si certaines fonctionnalités de cadre nécessitent un renvoyer "Texte de test"; code> renvoie un pointeur sur un lecture seule em> string littéral em>.
char * code> en entrée et que vous avez un
const char * code> (tel qu'un littéral en lecture seule), vous devez fournir une copie profonde de la chaîne à partir de ce
const char * code> à ces fonctions. p>
std :: string code>. (Si vous peut em> fonctionner avec
std :: string code> et em> toutes vos fonctions-structures prennent un
const char * code> entrée, Ensuite, je vous suggère de refactoriser votre code pour utiliser un
std :: string code> et transmettez la sortie de la méthode
C_STR () CODE> sur cette classe de chaîne à vos fonctions-cadre. ) p>
char * code>, vous pouvez toujours vous construire une petite classe d'adaptateur: P>
class Adapter
{
public:
Adapter(const& Adapter) = delete; /*don't try to copy me please*/
Adapter& operator=(const Adapter& ) = delete; /*don't try to copy me please*/
Adapter(const char* s) : m_s(::strdup(s))
{
}
~Adapter() /*free memory on destruction*/
{
::free(m_s); /*use free to release strdup memory*/
}
operator char*() /*implicit cast to char* */
{
return m_s;
}
private:
char* m_s;
};
Et si je veux "copier" le contenu const char * code> sur un
char * code> (donc, sans spécifier la taille fixe)? Je ne connais pas la taille de ce char *, depuis plus tard, je vais concatez d'autres caractères.
Oh, attendez. Je vois que je peux utiliser char * nom; code> et que
strcpy (nom, getname ()); code> aussi. Fondamentalement, j'ai eu une chaîne non longueur-définie qui servira ma tâche. Est-ce que c'est correct?
@Paizza Non. Utilisez quelque chose comme std :: String Name = getName (); code> puis passe
nom.c_str () code> à n'importe quelle fonction de cadre qui attend un
const * code>.
Il y a aussi STRDUP pour créer une copie d'une chaîne. Vous aurez besoin de libérer la mémoire plus tard, cependant, il est donc beaucoup plus facile d'utiliser std :: string code> en C ++.
Vous devez écrire nom.c_str () code>.
c_str code> est une fonction i>.
chaîne code> est bon, mais j'ai besoin de
char * code> plus tard, pas
const char * code> :(.
c_str () code> retour Const. Je pense que je ne peux pas passer un
chaîne code> à un
char * code> non?
Par intérêt, pourquoi avez-vous besoin d'un Char * code> plus tard?
Le seul moyen est de définir une taille fixe (deviner suffisamment) et utilisez Strcpy. C'est risqué, je peux avoir une violation de la mémoire d'accès si le char * a grandi plus que la taille que j'ai définie :(
@Bathsheba: Comme je l'ai dit, la fonction utilisée par le cadre Taks Char * code> en entrée, je ne peux pas les changer!
@pazza dans votre question, vous dites certaines fonctions dans un cadre que j'utilise utilisez const char * code> b> comme entrée i>
@ user2079303: Je me trompe, désolé! J'ai mis à jour la question. J'ai besoin de char *
D'ACCORD; Pensez à utiliser quelque chose sur les lignes de la classe que je donne dans la réponse.
La meilleure habitude de ce type de conversion consiste à utiliser Un deuxième meilleur utilise puisque le cadre que vous utilisez prend Si vous avez besoin d'un pointeur non constitué, il n'y a aucun moyen de copier la chaîne. Vous pouvez faire une fonction qui le fait pour vous, mais vous resterez responsable de libérer les copies que vous en obtenez: p> std :: chaîne code> tout au long de votre code. Étant donné que le cadre que vous utilisez prend
const char * code> comme entrée, vous pouvez toujours le transmettre les résultats de
c_str () code>
Appelez sur votre std :: string code>:
const char * code> dans votre code: p>
const char * code> vous sont bons ici aussi. P>
Vous pouvez explicitement le jeter. (char *) getname () code>. Mais vous ne devriez probablement pas. Parce que le bit
const code> signifie quelque chose comme "promettez de ne pas le changer". Donc, si j'ai une fonction
Void FOO (Const Char * String) Code> Je suis Saiing: "Donnez-moi un pointeur à une chaîne. Je ne le changerai pas."
Et si vous déclarez une variable
const char * string = "bonjour"; code> vous dites, cette chaîne ne doit pas être modifiée. Et parce que vous faites cette promesse, le compilateur sait et peut rendre votre code plus efficace. C'est pourquoi:
const char* a = "hello";
const char* b = "hello";
(a==b); //is probably true
Pourquoi suggérez-vous des moulages potentiellement dangereux? Le seul moyen correct d'obtenir une chaîne non-Const C à partir d'un littéral de chaîne C ++ est de le copier. Toute tentative de modification de la version non créée non-const est UB. S'il vous plaît ne proposez pas une méthode qui permettra (presque certainement) entraînera le diagnostic de comportement du programme sur la ligne.
Que veux-tu faire? Si vous ne voulez pas changer la chaîne, le premier idiome vous sert et n'utilise pas de mémoire supplémentaire; Si vous souhaitez modifier la chaîne, vous devez copier son contenu ailleurs (vous avez donc besoin de Strcpy ou similaire).