Il ne se convertira pas automatiquement (Dieu merci). Vous devrez utiliser la méthode c_str()
pour obtenir la version de la chaîne C.
std::string str = "string";
const char *cstr = str.c_str();
Notez qu'il renvoie un const char *
; vous n'êtes pas autorisé à modifier la chaîne de style C renvoyée par c_str()
. Si vous souhaitez le traiter, vous devrez d'abord le copier:
std::string str = "string";
char *cstr = new char[str.length() + 1];
strcpy(cstr, str.c_str());
// do stuff
delete [] cstr;
Ou en C ++ moderne:
std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);
c_str
complètement cette folie.vector
a été inventé précisément comme un wrapper pour les tableaux dynamiques, donc ne pas l'utiliser semble au mieux une opportunité manquée, et en violation de l'esprit du C ++ au pire.std::string
cela se convertirait automatiquement), puis j'explique ce qu'il devrait utiliser, avec un exemple de code court. En pensant à l'avenir, j'explique également certains effets secondaires de l'utilisation de cette fonction, dont l'un est que vous ne pouvez pas modifier la chaîne renvoyée parc_str()
. Vous voyez par erreur mes courts exemples comme un véritable code de résolution de problèmes, ce qui n'est pas le cas.std::vector<char>
).Plus de détails ici , et ici mais vous pouvez utiliser
la source
Si j'avais besoin d'une copie brute modifiable du contenu d'une chaîne c ++, alors je ferais ceci:
et ensuite:
Alors pourquoi ne pas jouer avec std :: vector ou new [] comme n'importe qui d'autre? Parce que quand j'ai besoin d'une chaîne char * brute de style C mutable, alors parce que je veux appeler le code C qui change la chaîne et le code C désalloue les choses avec free () et alloue avec malloc () (strdup utilise malloc) . Donc, si je passe ma chaîne brute à une fonction X écrite en C, cela pourrait avoir une contrainte sur son argument qu'elle doit allouer sur le tas (par exemple si la fonction peut vouloir appeler realloc sur le paramètre). Mais il est très peu probable qu'il attende un argument alloué avec (certains redéfinis par l'utilisateur) new []!
la source
strdup
vient.(Cette réponse s'applique uniquement à C ++ 98.)
S'il vous plaît, n'utilisez pas de brut
char*
.la source
vector<char>(str.c_str(), str.c_str() + str.size() + 1)
, sans affecter le pointeur char à un temporaire?std::basic_string<>::c_str()
est valide jusqu'à ce que lestring
soit modifié ou détruit. Cela implique également qu'il renvoie la même valeur lors des appels suivants tant que lestring
n'est pas modifié.vector
de cette façon. Et si l'on devait écrire du code sans exception sans mécanisme RAII (c'est-à-dire en utilisant des pointeurs bruts), la complexité du code serait beaucoup plus élevée que cette simple ligne unique.vector
a une énorme quantité de frais généraux et de complexité. Si vous avez besoin d'un tableau de caractères mutable , alors en fait, un vecteur de caractères est à peu près le wrapper C ++ idéal. Si votre exigence appelle simplement un pointeur const-char, alors utilisez-lec_str()
et vous avez terminé.Si vous voulez juste une chaîne de style C représentant le même contenu:
Si vous voulez une chaîne de style C avec un nouveau contenu, une façon (étant donné que vous ne connaissez pas la taille de la chaîne au moment de la compilation) est l'allocation dynamique:
N'oubliez pas
delete[]
plus tard.Si vous souhaitez plutôt un tableau alloué statiquement et de longueur limitée:
std::string
ne se convertit pas implicitement à ces types pour la simple raison que le faire est généralement une odeur de conception. Assurez-vous d'en avoir vraiment besoin.Si vous en avez vraiment besoin
char*
, la meilleure façon est probablement:la source
&str.front(), &str.back()
(qui ne sont pas présents dans C ++ 03) au lieu des plus courantsstr.begin()
etstr.end()
?str.begin()
, ou mêmestd::begin(str)
, comme un itérateur? Je ne crois passtring
avoir d'obligation d'être dans une mémoire contiguë commevector
, ou l'a-t-il?&back() + 1
, pas&back()
Ce serait mieux comme un commentaire sur la réponse de Bobobobo, mais je n'ai pas de représentant pour cela. Il accomplit la même chose mais avec de meilleures pratiques.
Bien que les autres réponses soient utiles, si vous avez besoin de convertir
std::string
enchar*
explicit sans const,const_cast
c'est votre ami.Notez que cela ne vous donnera pas une copie des données; il vous donnera un pointeur sur la chaîne. Ainsi, si vous modifiez un élément de
chr
, vous modifierezstr
.la source
En supposant que vous ayez juste besoin d'une chaîne de style C pour passer en entrée:
la source
Pour être strictement pédant, vous ne pouvez pas "convertir une chaîne std :: en un type de données char * ou char []."
Comme les autres réponses l'ont montré, vous pouvez copier le contenu de la chaîne std :: dans un tableau char, ou créer un const char * dans le contenu de la chaîne std :: afin de pouvoir y accéder dans un "style C" .
Si vous essayez de changer le contenu de la chaîne std ::, le type std :: string possède toutes les méthodes pour faire tout ce dont vous pourriez avoir besoin.
Si vous essayez de le passer à une fonction qui prend un char *, il y a std :: string :: c_str ().
la source
Voici une version plus robuste de
Protocol Buffer
la source
if (str[str.length()-1] != 0) str.push_back(0)
Conversion dans le style OOP
converter.hpp
converter.cpp
usage
la source
Pour être complet, n'oubliez pas
std::string::copy()
.std::string::copy()
NUL ne se termine pas. Si vous devez garantir un terminateur NUL pour une utilisation dans les fonctions de chaîne C:la source
Vous pouvez le faire en utilisant l'itérateur.
Bonne chance.
la source
Une version sûre de la réponse char * d'orlp en utilisant unique_ptr:
la source
Pour obtenir un à
const char *
partir d'unestd::string
utilisation de lac_str()
fonction membre:Pour obtenir un non-const à
char *
partir d'un,std::string
vous pouvez utiliser ladata()
fonction membre qui retourne un pointeur non-const depuis C ++ 17:Pour les anciennes versions du langage, vous pouvez utiliser la construction de plages pour copier la chaîne dans un vecteur à partir duquel un pointeur non const peut être obtenu:
Mais attention, cela ne vous permettra pas de modifier la chaîne contenue dans
str
, seules les données de la copie peuvent être modifiées de cette façon. Notez qu'il est particulièrement important dans les anciennes versions de la langue d'utiliserc_str()
ici, car à l'époque, ilstd::string
n'était pas garanti que la terminaison null soit terminée jusqu'à ce qu'ellec_str()
soit appelée.la source
la source
Alternativement, vous pouvez utiliser des vecteurs pour obtenir un caractère inscriptible * comme illustré ci-dessous;
la source
Cela fonctionnera également
la source