web-dev-qa-db-fra.com

std :: string to char *

Je veux convertir un std :: string en un type de données char * ou char [].

std::string str = "string";
char* chr = str;

Résultats en: "erreur: impossible de convertir‘ std :: string ’en" char "...".

Quelles méthodes sont disponibles pour le faire?

291
Mario

Il ne 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 const char *; vous n'êtes pas autorisé à modifier la chaîne de style C renvoyée par c_str(). Si vous voulez 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);
601
orlp

Plus de détails ici , et ici mais vous pouvez utiliser

string str = "some string" ;
char *cstr = &str[0];
133
bobobobo

Si j'avais besoin d'une copie brute modifiable du contenu de la chaîne d'un c ++, je procéderais ainsi:

std::string str = "string";
char* chr = strdup(str.c_str());

et ensuite:

free(chr); 

Alors pourquoi ne pas jouer avec std :: vector ou new [] comme n'importe qui? Parce que quand j'ai besoin d'une chaîne * générique de style C mutable, alors parce que je veux appeler du code C qui modifie la chaîne et que le code C libère des éléments avec free () et alloue avec malloc () (strdup utilise malloc). Donc, si je passe ma chaîne brute à une fonction X écrit en C il pourrait avoir une contrainte sur l'argument qu'il doit allouer sur le tas (par exemple si la fonction peut vouloir appeler realloc sur le paramètre). Mais il est hautement improbable qu’il s’attende à ce qu’un argument soit attribué avec un nouveau []!

37
Nordic Mainframe

(Cette réponse s'applique uniquement à C++ 98.)

S'il vous plaît, n'utilisez pas un char* brut.

std::string str = "string";
std::vector<char> chars(str.c_str(), str.c_str() + str.size() + 1u);
// use &chars[0] as a char*
21
ildjarn
  • Si vous voulez juste une chaîne de style C représentant le même contenu:

    char const* ca = str.c_str();
    
  • Si vous voulez une chaîne de style C avec un nouveau contenu , une manière (étant donné que vous ne connaissez pas la taille de la chaîne au moment de la compilation) est dynamique. allocation:

    char* ca = new char[str.size()+1];
    std::copy(str.begin(), str.end(), ca);
    ca[str.size()] = '\0';
    

    N'oubliez pas de delete[] plus tard.

  • Si vous souhaitez plutôt un tableau alloué statiquement et de longueur limitée:

    size_t const MAX = 80; // maximum number of chars
    char ca[MAX] = {};
    std::copy(str.begin(), (str.size() >= MAX ? str.begin() + MAX : str.end()), ca);
    

std::string ne se convertit pas implicitement en ces types pour la simple raison que devoir le faire est généralement une odeur de design. Assurez-vous que vous en avez réellement besoin .

Si vous définitivement avez besoin d'un char* _, le meilleur moyen est probablement le suivant:

vector<char> v(str.begin(), str.end());
char* ca = &v[0]; // pointer to start of vector
15

Ce serait mieux comme commentaire sur la réponse de bobobobo, mais je n'ai pas le représentant pour cela. Il accomplit la même chose mais avec de meilleures pratiques.

Bien que les autres réponses soient utiles, si jamais vous avez besoin de convertir std::string en char* explicitement sans const, const_cast est votre ami.

std::string str = "string";
char* chr = const_cast<char*>(str.c_str());

Notez que ceci not vous donnera une copie des données; cela vous donnera un pointeur sur la chaîne. Ainsi, si vous modifiez un élément de chr, vous modifierez str.

10
hairlessbear

En supposant que vous ayez juste besoin d’une chaîne de style C pour passer en entrée:

std::string str = "string";
const char* chr = str.c_str();
6
Mark B

Pour être strictement pédant, vous ne pouvez pas "convertir un std :: string en un type de données char * ou char []".

Comme les autres réponses l'ont montré, vous pouvez copier le contenu de std :: string dans un tableau de caractères ou créer un caractère const * au contenu de std :: string afin de pouvoir y accéder dans un "style C". .

Si vous essayez de changer le contenu de std :: string, le type std :: string dispose de toutes les méthodes pour faire tout ce que vous pourriez avoir besoin de faire.

Si vous essayez de le transmettre à une fonction qui prend un caractère *, il existe std :: string :: c_str ().

5
Rob K

Pour être complet, n'oubliez pas std::string::copy().

std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];

str.copy(chrs, MAX);

std::string::copy() ne termine pas NUL. Si vous avez besoin d'un terminateur NUL à utiliser dans les fonctions de chaîne C:

std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];

memset(chrs, '\0', MAX);
str.copy(chrs, MAX-1);
4
Jeffery Thomas

Voici une version plus robuste de Protocol Buffer

char* string_as_array(string* str)
{
    return str->empty() ? NULL : &*str->begin();
}

// test codes
std::string mystr("you are here");
char* pstr = string_as_array(&mystr);
cout << pstr << endl; // you are here
4
zangw
char* result = strcpy((char*)malloc(str.length()+1), str.c_str());
3
cegprakash

Vous pouvez également utiliser des vecteurs pour obtenir un caractère en écriture *, comme illustré ci-dessous;

//this handles memory manipulations and is more convenient
string str;
vector <char> writable (str.begin (), str.end) ;
writable .Push_back ('\0'); 
char* cstring = &writable[0] //or &*writable.begin () 

//Goodluck  
3
user5616653

Vous pouvez le faire en utilisant itérateur.

std::string str = "string";
std::string::iterator p=str.begin();
char* chr = &(*p);

Bonne chance.

3
TS.PARK

Une version sécurisée de la réponse char * de orlp en utilisant unique_ptr:

std::string str = "string";
auto cstr = std::make_unique<char[]>(str.length() + 1);
strcpy(cstr.get(), str.c_str());
2
Enhex

Conversion dans le style OOP

convertisseur.hpp

class StringConverter {
    public: static char * strToChar(std::string str);
};

convertisseur.cpp

char * StringConverter::strToChar(std::string str)
{
    return (char*)str.c_str();
}

usage

StringConverter::strToChar("converted string")
2

Cela fonctionnera aussi

std::string s;
std::cout<<"Enter the String";
std::getline(std::cin, s);
char *a=new char[s.size()+1];
a[s.size()]=0;
memcpy(a,s.c_str(),s.size());
std::cout<<a;  
2
Genocide_Hoax