std::string naar char*

Ik wil een std::stringconverteren naar een char*of char[]gegevenstype.

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

Resulteert in: “fout: kan ‘std::string’ niet converteren naar ‘char’ …”.

Welke methoden zijn er beschikbaar om dit te doen?


Antwoord 1, autoriteit 100%

Het wordt niet automatisch geconverteerd (godzijdank). Je moet de methode c_str()gebruiken om de C-stringversie te krijgen.

std::string str = "string";
const char *cstr = str.c_str();

Merk op dat het een const char *teruggeeft; je mag de C-stijl string die wordt geretourneerd door c_str()niet wijzigen. Als je het wilt verwerken, moet je het eerst kopiëren:

std::string str = "string";
char *cstr = new char[str.length() + 1];
strcpy(cstr, str.c_str());
// do stuff
delete [] cstr;

Of in moderne C++:

std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);

Antwoord 2, autoriteit 25%

Meer details hieren hiermaar je kunt

. gebruiken

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

Antwoord 3, autoriteit 6%

Als ik een veranderlijke onbewerkte kopie van de tekenreeksinhoud van een c++ nodig zou hebben, dan zou ik dit doen:

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

en later:

free(chr); 

Dus waarom speel ik niet zoals iedereen met std::vector of new[]? Omdat wanneer ik een veranderlijke C-stijl raw char * string nodig heb, dan omdat ik C-code wil aanroepen die de string verandert en C-code dingen vrijgeeft met free() en toewijst met malloc() (strdup gebruikt malloc). Dus als ik mijn onbewerkte tekenreeks doorgeef aan een functie X geschreven in C, kaneen beperking hebben op het argument dat het op de heap moet worden toegewezen (bijvoorbeeld als de functie wil misschien realloc op de parameter aanroepen). Maar het is hoogst onwaarschijnlijk dat het een argument zou verwachten dat is toegewezen met (sommige door de gebruiker opnieuw gedefinieerde) new[]!


Antwoord 4, autoriteit 3%

(Dit antwoord is alleen van toepassing op C++98.)

Gebruik geen onbewerkte char*.

std::string str = "string";
std::vector<char> chars(str.c_str(), str.c_str() + str.size() + 1u);
// use &chars[0] as a char*

Antwoord 5, autoriteit 2%

  • Als je alleen een tekenreeks in C-stijl wilt die dezelfde inhoud vertegenwoordigt:

    char const* ca = str.c_str();
    
  • Als je een C-stijl string met nieuweinhoud wilt, is een manier (aangezien je de stringgrootte niet weet tijdens het compileren) dynamische toewijzing:

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

    Vergeet niet om het later te delete[].

  • Als u in plaats daarvan een statisch toegewezen array van beperkte lengte wilt:

    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::stringconverteert niet impliciet naar deze typen om de eenvoudige reden dat dit meestal een ontwerpgeur is. Zorg ervoor dat je het echtnodig hebt.

Als je absoluuteen char*nodig hebt, is de bestemanier waarschijnlijk:

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

Antwoord 6, autoriteit 2%

Dit zou beter zijn als commentaar op het antwoord van bobobobo, maar daar heb ik de vertegenwoordiger niet voor. Het bereikt hetzelfde, maar met betere praktijken.

Hoewel de andere antwoorden nuttig zijn, als u ooit std::stringexpliciet moet converteren naar char*zonder const, is const_castje vriend.

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

Merk op dat dit u geeneen kopie van de gegevens geeft; het geeft je een verwijzing naar de string. Als u dus een element van chrwijzigt, wijzigt u str.


Antwoord 7

Ervan uitgaande dat je alleen een C-stijl string nodig hebt om als invoer door te geven:

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

Antwoord 8

Om een const char *van een std::stringte verkrijgen, gebruikt u de c_str()lidfunctie :

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

Om een niet-const char *van een std::stringte verkrijgen, kun je de data()lidfunctie die een non-const pointer retourneert sinds C++17 :

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

Voor oudere versies van de taal, kun je range-constructie gebruiken om de string te kopiëren naar een vector waaruit een non-const pointer kan worden verkregen:

std::string str = "string";
std::vector<char> str_copy(str.c_str(), str.c_str() + str.size() + 1);
char* chr = str_copy.data();

Maar pas op dat je hiermee de string in strniet kunt wijzigen, alleen de gegevens van de kopie kunnen op deze manier worden gewijzigd. Merk op dat het vooral belangrijk is in oudere versies van de taal om c_str()hier te gebruiken, omdat in die tijd std::stringniet gegarandeerd was dat het null beëindigd werd tot c_str()werd aangeroepen.


Antwoord 9

Om strikt pedant te zijn, kun je “een std::string niet converteren naar een char*- of char[]-gegevenstype.”

Zoals de andere antwoorden hebben aangetoond, kunt u de inhoud van de std::string kopiëren naar een char-array, of een const char* maken naar de inhoud van de std::string zodat u deze kunt openen in een ” C-stijl”.

Als je de inhoud van de std::string probeert te veranderen, heeft het type std::string alle methoden om alles te doen wat je er eventueel mee zou kunnen doen.

Als je het probeert door te geven aan een functie waarvoor een char* nodig is, is er std::string::c_str().


Antwoord 10

Hier is nog een robuuste versie van 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

Antwoord 11

Conversie in OOP-stijl

converter.hpp

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

converter.cpp

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

gebruik

StringConverter::strToChar("converted string")

Antwoord 12

Vergeet voor de volledigheid std::string::copy()niet.

std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
str.copy(chrs, MAX);

std::string::copy()beëindigt NUL niet. Als u moet zorgen voor een NUL-terminator voor gebruik in C-stringfuncties:

std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
memset(chrs, '\0', MAX);
str.copy(chrs, MAX-1);

Antwoord 13

Je kunt het maken met iterator.

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

Veel succes.


Antwoord 14

Een veilige versie van het char*-antwoord van orlp met unique_ptr:

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

Antwoord 15

char* result = strcpy((char*)malloc(str.length()+1), str.c_str());

Antwoord 16

Als alternatief kunt u vectoren gebruiken om een beschrijfbaar teken* te krijgen, zoals hieronder wordt aangetoond;

//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  

Antwoord 17

Dit werkt ook

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;  

Antwoord 18

Geen instantie heeft ooit sprintf genoemd?

std::string s;
char * c;
sprintf(c, "%s", s.c_str());

Other episodes