Wie konvertiere ich einen std :: string in const char * oder char *?

893

Wie kann ich ein std::stringin ein char*oder ein konvertieren const char*?

user37875
quelle
2
Anstelle von: char * writable = new char [str.size () + 1]; Sie können char writable [str.size () + 1] verwenden. Dann müssen Sie sich keine Gedanken mehr über das Löschen von beschreibbaren oder Ausnahmebehandlungen machen.
7
Sie können str.size () nur verwenden, wenn die Größe zum Zeitpunkt der Kompilierung bekannt ist. Außerdem kann Ihr Stapel überlaufen, wenn der Wert für die feste Größe sehr groß ist.
Paulm
1
char * result = strcpy ((char *) malloc (str.length () + 1), str.c_str ());
Cegprakash
7
@cegprakash strcpyund mallocsind nicht wirklich die C ++ Art.
Boycy
4
Nein, char* dest = new char[str.length() + 1]; std::copy(str.begin(), str.end(), dest)wäre aber idiomatischer C ++. strcpy()und malloc()sind nicht falsch oder problematisch, aber es scheint inkonsistent, eine C ++ - Zeichenfolge und C-Bibliotheksfunktionen mit C ++ - Entsprechungen im selben Codeblock zu verwenden.
Boycy

Antworten:

1055

Wenn Sie a nur std::stringan eine Funktion übergeben möchten, die const char*Sie benötigen , können Sie diese verwenden

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

Wenn Sie eine beschreibbare Kopie erhalten möchten char *, können Sie dies folgendermaßen tun:

std::string str;
char * writable = new char[str.size() + 1];
std::copy(str.begin(), str.end(), writable);
writable[str.size()] = '\0'; // don't forget the terminating 0

// don't forget to free the string after finished using it
delete[] writable;

Bearbeiten : Beachten Sie, dass das oben Genannte nicht ausnahmesicher ist. Wenn zwischen dem newAnruf und dem deleteAnruf etwas ausgelöst wird, geht Speicher verloren, da nichts deleteautomatisch nach Ihnen ruft . Es gibt zwei unmittelbare Möglichkeiten, dies zu lösen.

boost :: scoped_array

boost::scoped_array löscht den Speicher für Sie, wenn Sie den Gültigkeitsbereich verlassen:

std::string str;
boost::scoped_array<char> writable(new char[str.size() + 1]);
std::copy(str.begin(), str.end(), writable.get());
writable[str.size()] = '\0'; // don't forget the terminating 0

// get the char* using writable.get()

// memory is automatically freed if the smart pointer goes 
// out of scope

std :: vector

Dies ist der Standardweg (erfordert keine externe Bibliothek). Sie verwenden std::vector, wodurch der Speicher für Sie vollständig verwaltet wird.

std::string str;
std::vector<char> writable(str.begin(), str.end());
writable.push_back('\0');

// get the char* using &writable[0] or &*writable.begin()
Johannes Schaub - litb
quelle
41
Verwenden Sie einfach char * result = strdup (str.c_str ());
Jasper Bekkers
63
Sie könnten, aber strdup ist keine AC- oder C ++ - Standardfunktion, es ist von posix :)
Johannes Schaub - litb
14
Was ich im Allgemeinen wahrscheinlich bevorzugen würde, ist std :: vector <char> writable (str.begin (), str.end ()); writable.push_back ('\ 0'); char * c = & beschreibbar [0];
Johannes Schaub - litb
17
std :: copy ist die c ++ - Methode, um dies zu tun, ohne auf den Zeichenfolgenzeiger zugreifen zu müssen. Ich versuche, C-Funktionen so weit wie möglich zu vermeiden.
Johannes Schaub - litb
16
Ab C ++ 17 wird std::string::data()jetzt a CharT*anstelle von a zurückgegeben const CharT*. Es könnte eine gute Idee sein, diese Antwort zu aktualisieren :)
Rakete1111
192

Gegeben sagen ...

std::string x = "hello";

Abrufen eines "char *" oder "const char *" aus einem "String"

So erhalten Sie einen Zeichenzeiger, der gültig ist, während er xim Gültigkeitsbereich bleibt und nicht weiter geändert wird

C ++ 11 vereinfacht die Dinge; Die folgenden Optionen bieten Zugriff auf denselben internen Zeichenfolgenpuffer:

const char* p_c_str = x.c_str();
const char* p_data  = x.data();
char* p_writable_data = x.data(); // for non-const x from C++17 
const char* p_x0    = &x[0];

      char* p_x0_rw = &x[0];  // compiles iff x is not const...

Alle oben genannten Zeiger enthalten denselben Wert - die Adresse des ersten Zeichens im Puffer. Sogar eine leere Zeichenfolge hat ein "erstes Zeichen im Puffer", da C ++ 11 garantiert, dass nach dem explizit zugewiesenen Zeichenfolgeninhalt immer ein zusätzliches NUL / 0-Abschlusszeichen beibehalten wird (z. B. std::string("this\0that", 9)wird ein Puffer gespeichert "this\0that\0").

Angesichts eines der oben genannten Hinweise:

char c = p[n];   // valid for n <= x.size()
                 // i.e. you can safely read the NUL at p[x.size()]

Nur für den nicht - constZeiger p_writable_dataund aus &x[0]:

p_writable_data[n] = c;
p_x0_rw[n] = c;  // valid for n <= x.size() - 1
                 // i.e. don't overwrite the implementation maintained NUL

Das Schreiben eines NUL an einer anderen Stelle in der Zeichenfolge ändert nichts an den string's size(); string's dürfen eine beliebige Anzahl von NULs enthalten - sie werden von nicht speziell behandelt std::string(wie in C ++ 03).

In C ++ 03 waren die Dinge erheblich komplizierter (wichtige Unterschiede hervorgehoben ):

  • x.data()

    • kehrt const char*zum internen Puffer der Zeichenfolge zurück , der vom Standard nicht benötigt wurde, um mit einem NUL abzuschließen (dh es können nicht ['h', 'e', 'l', 'l', 'o']initialisierte oder Garbage-Werte folgen, wobei versehentliche Zugriffe darauf ein undefiniertes Verhalten aufweisen ).
      • x.size()Zeichen sind sicher zu lesen, dh x[0]durchx[x.size() - 1]
      • Für leere Zeichenfolgen ist ein Nicht-NULL-Zeiger garantiert, zu dem 0 sicher hinzugefügt werden kann (Hurra!), aber Sie sollten diesen Zeiger nicht dereferenzieren.
  • &x[0]

    • für leere Strings hat dies ein undefiniertes Verhalten (21.3.4)
      • zB gegeben f(const char* p, size_t n) { if (n == 0) return; ...whatever... }darf man nicht anrufen f(&x[0], x.size());wann x.empty()- einfach benutzen f(x.data(), ...).
    • ansonsten wie folgt x.data()aber:
      • für nicht const xergibt dies einen Nichtzeiger const char*; Sie können den Inhalt von Zeichenfolgen überschreiben
  • x.c_str()

    • kehrt const char*zu einer ASCIIZ-Darstellung (NUL-terminiert) des Werts zurück (dh ['h', 'e', ​​'l', 'l', 'o', '\ 0']).
    • obwohl nur wenige , wenn irgendwelche Implementierungen dies wünschen, die C ++ 03 Standard - Wortlaut wurde der String Umsetzung die Freiheit zu ermöglichen , eine zu schaffen verschiedene NUL-terminierten Puffer im Fluge , von der potenziell nicht-NUL beendet „ausgesetzt“ Puffer durch x.data()und&x[0]
    • x.size() + 1 Zeichen sind sicher zu lesen.
    • garantiert sicher auch für leere Strings (['\ 0']).

Folgen des Zugriffs auf externe Rechtsindizes

Unabhängig davon, wie Sie einen Zeiger erhalten, dürfen Sie nicht weiter vom Zeiger entfernt auf den Speicher zugreifen als auf die in den obigen Beschreibungen garantierten Zeichen. Versuche, dies zu tun, haben ein undefiniertes Verhalten , mit einer sehr realen Wahrscheinlichkeit von Anwendungsabstürzen und Müllergebnissen, selbst bei Lesevorgängen, und zusätzlich Großhandelsdaten, Stapelbeschädigungen und / oder Sicherheitslücken für Schreibvorgänge.

Wann werden diese Zeiger ungültig?

Wenn Sie eine Elementfunktion aufrufen string, die die stringKapazität ändert oder weitere Kapazität reserviert, werden alle zuvor von einer der oben genannten Methoden zurückgegebenen Zeigerwerte ungültig . Sie können diese Methoden erneut verwenden, um einen weiteren Zeiger abzurufen. (Die Regeln sind die gleichen wie für Iteratoren in strings).

Siehe auch So erhalten Sie einen gültigen Zeichenzeiger, auch wenn er den Gültigkeitsbereich xverlässt oder weiter unten geändert wird ....

Also, was ist besser zu verwenden?

Verwenden .c_str()Sie ab C ++ 11 ASCIIZ-Daten und .data()"binäre" Daten (weiter unten erläutert).

Verwenden Sie in C ++ 03, .c_str()sofern dies nicht .data()ausreichend ist, und ziehen .data()Sie es vor, &x[0]da es für leere Zeichenfolgen sicher ist.

... versuchen Sie, das Programm so gut zu verstehen, data()dass es gegebenenfalls verwendet werden kann, oder Sie werden wahrscheinlich andere Fehler machen ...

Das von garantierte ASCII-NUL-Zeichen '\ 0' .c_str()wird von vielen Funktionen als Sentinel-Wert verwendet, der das Ende relevanter und für den Zugriff sicherer Daten angibt. Dies gilt sowohl für C ++ - nur Funktionen wie say fstream::fstream(const char* filename, ...)und Funktionen, die mit C geteilt werden, wie strchr(), und printf().

Angesichts der Tatsache .c_str(), dass die Garantien von C ++ 03 für den zurückgegebenen Puffer sehr hoch sind .data(), können Sie sie immer sicher verwenden .c_str(), aber manchmal nicht, weil:

  • Die Verwendung von .data()kommuniziert mit anderen Programmierern, die den Quellcode lesen, dass die Daten nicht ASCIIZ sind (stattdessen verwenden Sie die Zeichenfolge zum Speichern eines Datenblocks (der manchmal nicht einmal wirklich textuell ist)) oder an den Sie ihn weitergeben eine weitere Funktion, die es als Block von "binären" Daten behandelt. Dies kann eine wichtige Erkenntnis sein, um sicherzustellen, dass die Codeänderungen anderer Programmierer die Daten weiterhin ordnungsgemäß verarbeiten.
  • Nur C ++ 03: Es besteht eine geringe Wahrscheinlichkeit, dass Ihre stringImplementierung zusätzliche Speicherzuweisung und / oder Datenkopie durchführen muss, um den NUL-terminierten Puffer vorzubereiten

Als weiterer Hinweis: Wenn die Parameter einer Funktion das ( const) erfordern, char*aber nicht darauf bestehen, dass sie abgerufen werden x.size(), benötigt die Funktion wahrscheinlich eine ASCIIZ-Eingabe. Dies .c_str()ist eine gute Wahl (die Funktion muss wissen, wo der Text irgendwie endet, wenn dies nicht der Fall ist Als separater Parameter kann es sich nur um eine Konvention wie ein Längenpräfix oder einen Sentinel oder eine feste erwartete Länge handeln.

So erhalten Sie einen Zeichenzeiger, der auch dann gültig ist, wenn er den Gültigkeitsbereich xverlässt oder weiter geändert wird

Sie müssen den Inhalt von in einen neuen Speicherbereich außerhalb kopieren . Dieser externe Puffer kann sich an vielen Stellen befinden, z. B. in einer anderen oder einer Zeichenarray-Variablen. Er kann eine andere Lebensdauer haben oder nicht als aufgrund eines anderen Bereichs (z. B. Namespace, global, statisch, Heap, gemeinsam genutzter Speicher, Speicherzuordnungsdatei). .string xxstringx

So kopieren Sie den Text std::string xin ein unabhängiges Zeichenarray:

// USING ANOTHER STRING - AUTO MEMORY MANAGEMENT, EXCEPTION SAFE
std::string old_x = x;
// - old_x will not be affected by subsequent modifications to x...
// - you can use `&old_x[0]` to get a writable char* to old_x's textual content
// - you can use resize() to reduce/expand the string
//   - resizing isn't possible from within a function passed only the char* address

std::string old_x = x.c_str(); // old_x will terminate early if x embeds NUL
// Copies ASCIIZ data but could be less efficient as it needs to scan memory to
// find the NUL terminator indicating string length before allocating that amount
// of memory to copy into, or more efficient if it ends up allocating/copying a
// lot less content.
// Example, x == "ab\0cd" -> old_x == "ab".

// USING A VECTOR OF CHAR - AUTO, EXCEPTION SAFE, HINTS AT BINARY CONTENT, GUARANTEED CONTIGUOUS EVEN IN C++03
std::vector<char> old_x(x.data(), x.data() + x.size());       // without the NUL
std::vector<char> old_x(x.c_str(), x.c_str() + x.size() + 1);  // with the NUL

// USING STACK WHERE MAXIMUM SIZE OF x IS KNOWN TO BE COMPILE-TIME CONSTANT "N"
// (a bit dangerous, as "known" things are sometimes wrong and often become wrong)
char y[N + 1];
strcpy(y, x.c_str());

// USING STACK WHERE UNEXPECTEDLY LONG x IS TRUNCATED (e.g. Hello\0->Hel\0)
char y[N + 1];
strncpy(y, x.c_str(), N);  // copy at most N, zero-padding if shorter
y[N] = '\0';               // ensure NUL terminated

// USING THE STACK TO HANDLE x OF UNKNOWN (BUT SANE) LENGTH
char* y = alloca(x.size() + 1);
strcpy(y, x.c_str());

// USING THE STACK TO HANDLE x OF UNKNOWN LENGTH (NON-STANDARD GCC EXTENSION)
char y[x.size() + 1];
strcpy(y, x.c_str());

// USING new/delete HEAP MEMORY, MANUAL DEALLOC, NO INHERENT EXCEPTION SAFETY
char* y = new char[x.size() + 1];
strcpy(y, x.c_str());
//     or as a one-liner: char* y = strcpy(new char[x.size() + 1], x.c_str());
// use y...
delete[] y; // make sure no break, return, throw or branching bypasses this

// USING new/delete HEAP MEMORY, SMART POINTER DEALLOCATION, EXCEPTION SAFE
// see boost shared_array usage in Johannes Schaub's answer

// USING malloc/free HEAP MEMORY, MANUAL DEALLOC, NO INHERENT EXCEPTION SAFETY
char* y = strdup(x.c_str());
// use y...
free(y);

Andere Gründe, um ein zu wollen char*oder const char*aus einem generiertstring

Oben haben Sie gesehen, wie Sie ein ( const) erhalten char*und wie Sie eine Kopie des Textes unabhängig vom Original stringerstellen. Aber was können Sie damit tun ? Ein paar Beispiele ...

  • Geben Sie "C" -Code Zugriff auf den stringText von C ++ , wie inprintf("x is '%s'", x.c_str());
  • Kopieren Sie xden Text in einen Puffer, der vom Aufrufer Ihrer Funktion angegeben wurde (z. B. strncpy(callers_buffer, callers_buffer_size, x.c_str())), oder in einen flüchtigen Speicher, der für Geräte-E / A verwendet wird (z. B. for (const char* p = x.c_str(); *p; ++p) *p_device = *p;).
  • Hängen Sie xden Text an ein Zeichenarray an, das bereits ASCIIZ-Text enthält (z. B. strcat(other_buffer, x.c_str())). Achten Sie darauf, den Puffer nicht zu überlaufen (in vielen Situationen müssen Sie ihn möglicherweise verwenden strncat).
  • eine const char*oder char*von einer Funktion zurückgeben (möglicherweise aus historischen Gründen - der Client verwendet Ihre vorhandene API - oder aus C-Kompatibilität möchten Sie keine zurückgeben std::string, aber Ihre stringDaten für den Anrufer irgendwo kopieren )
    • Achten Sie darauf, keinen Zeiger zurückzugeben, der vom Aufrufer möglicherweise dereferenziert wird, nachdem eine lokale stringVariable, auf die dieser Zeiger zeigt, den Gültigkeitsbereich verlassen hat
    • Einige Projekte mit gemeinsam genutzten Objekten, die für verschiedene std::stringImplementierungen kompiliert / verknüpft wurden (z. B. STLport und Compiler-native), übergeben möglicherweise Daten als ASCIIZ, um Konflikte zu vermeiden
Tony Delroy
quelle
4
Schön. Ein weiterer Grund, ein char * (non const) zu wollen, ist der Betrieb mit MPI-Broadcast. Es sieht besser aus, wenn Sie nicht hin und her kopieren müssen. Ich hätte persönlich einen char * const getter zum String angeboten. Const-Zeiger, aber bearbeitbarer String. Obwohl es möglicherweise mit der impliziten Konvertierung von const char * zu string zu
tun hat
33

Verwenden Sie die .c_str()Methode für const char *.

Sie können &mystring[0]einen char *Zeiger abrufen, aber es gibt einige Fallstricke: Sie erhalten nicht unbedingt eine nullterminierte Zeichenfolge, und Sie können die Größe der Zeichenfolge nicht ändern. Sie müssen besonders darauf achten, keine Zeichen nach dem Ende der Zeichenfolge hinzuzufügen, da sonst ein Pufferüberlauf (und ein wahrscheinlicher Absturz) auftritt.

Es gab keine Garantie dafür, dass alle Zeichen bis C ++ 11 Teil desselben zusammenhängenden Puffers waren, aber in der Praxis std::stringfunktionierten alle bekannten Implementierungen trotzdem so. Siehe Zeigt "& s [0]" auf zusammenhängende Zeichen in einem std :: string? .

Beachten Sie, dass viele stringElementfunktionen den internen Puffer neu zuordnen und alle möglicherweise gespeicherten Zeiger ungültig machen. Am besten sofort verwenden und dann wegwerfen.

Mark Ransom
quelle
1
Sie sollten beachten, dass data () const char * :) zurückgibt. Was Sie meinen, ist & str [0], das eine zusammenhängende, aber nicht notwendige nullterminierte Zeichenfolge zurückgibt.
Johannes Schaub - litb
1
@ Litb, Argh! Das bekomme ich, wenn ich versuche, eine schnelle Antwort zu finden. Ich habe Ihre Lösung in der Vergangenheit verwendet und weiß nicht, warum es nicht das erste war, was mir in den Sinn kam. Ich habe meine Antwort bearbeitet.
Mark Ransom
2
Technisch gesehen ist der Speicher von std :: string nur in C ++ 0x zusammenhängend.
MSalters
1
@ MSalters, danke - das wusste ich nicht. Es würde mir jedoch schwer fallen, eine Implementierung zu finden, bei der dies jedoch nicht der Fall war.
Mark Ransom
2
char * result = strcpy (malloc (str.length () + 1), str.c_str ());
Cegprakash
21

C ++ 17

C ++ 17 (kommender Standard) ändert die Inhaltsangabe der Vorlage und basic_stringfügt eine nicht konstante Überladung von data():

charT* data() noexcept;

Rückgabe: Ein Zeiger p, so dass p + i == & Operator für jedes i in [0, size ()].


CharT const * von std::basic_string<CharT>

std::string const cstr = { "..." };
char const * p = cstr.data(); // or .c_str()

CharT * von std::basic_string<CharT>

std::string str = { "..." };
char * p = str.data();

C ++ 11

CharT const * von std::basic_string<CharT>

std::string str = { "..." };
str.c_str();

CharT * von std::basic_string<CharT>

Ab C ++ 11 heißt es im Standard:

  1. Die char-ähnlichen Objekte in einem basic_stringObjekt sind zusammenhängend zu speichern. Das heißt, für jedes basic_stringObjekt sgilt die Identität &*(s.begin() + n) == &*s.begin() + nfür alle Werte n, die 0 <= n < s.size().

  1. const_reference operator[](size_type pos) const;
    reference operator[](size_type pos);

    Rückgabe: *(begin() + pos)if pos < size(), andernfalls ein Verweis auf ein Objekt vom Typ CharTmit Wert CharT(); Der angegebene Wert darf nicht geändert werden.


  1. const charT* c_str() const noexcept;
    const charT* data() const noexcept;

    Rückgabe: Ein Zeiger p, so dass p + i == &operator[](i)für jeden iin [0,size()].

Es gibt verschiedene Möglichkeiten, einen nicht konstanten Zeichenzeiger zu erhalten.

1. Verwenden Sie den zusammenhängenden Speicher von C ++ 11

std::string foo{"text"};
auto p = &*foo.begin();

Profi

  • Einfach und kurz
  • Schnell (nur Methode ohne Kopie)

Nachteile

  • Final '\0'darf nicht geändert werden / ist nicht unbedingt Teil des nicht konstanten Speichers.

2. Verwenden Sie std::vector<CharT>

std::string foo{"text"};
std::vector<char> fcv(foo.data(), foo.data()+foo.size()+1u);
auto p = fcv.data();

Profi

  • Einfach
  • Automatische Speicherbehandlung
  • Dynamisch

Nachteile

  • Erfordert eine Zeichenfolgenkopie

3. Verwenden Sie std::array<CharT, N>if N, wenn die Kompilierungszeit konstant ist (und klein genug).

std::string foo{"text"};
std::array<char, 5u> fca;
std::copy(foo.data(), foo.data()+foo.size()+1u, fca.begin());

Profi

  • Einfach
  • Stapelspeicherbehandlung

Nachteile

  • Statisch
  • Erfordert eine Zeichenfolgenkopie

4. Rohspeicherzuordnung mit automatischer Speicherlöschung

std::string foo{ "text" };
auto p = std::make_unique<char[]>(foo.size()+1u);
std::copy(foo.data(), foo.data() + foo.size() + 1u, &p[0]);

Profi

  • Kleiner Speicherbedarf
  • Automatisches Löschen
  • Einfach

Nachteile

  • Erfordert eine Zeichenfolgenkopie
  • Statisch (dynamische Verwendung erfordert viel mehr Code)
  • Weniger Features als Vektor oder Array

5. Rohspeicherzuordnung mit manueller Handhabung

std::string foo{ "text" };
char * p = nullptr;
try
{
  p = new char[foo.size() + 1u];
  std::copy(foo.data(), foo.data() + foo.size() + 1u, p);
  // handle stuff with p
  delete[] p;
}
catch (...)
{
  if (p) { delete[] p; }
  throw;
}

Profi

  • Maximale 'Kontrolle'

Con

  • Erfordert eine Zeichenfolgenkopie
  • Maximale Haftung / Fehleranfälligkeit
  • Komplex
Pixelchemist
quelle
9

Ich arbeite mit einer API mit vielen Funktionen als Eingabe a char*.

Ich habe eine kleine Klasse erstellt, um diese Art von Problem zu lösen. Ich habe die RAII-Sprache implementiert.

class DeepString
{
        DeepString(const DeepString& other);
        DeepString& operator=(const DeepString& other);
        char* internal_; 

    public:
        explicit DeepString( const string& toCopy): 
            internal_(new char[toCopy.size()+1]) 
        {
            strcpy(internal_,toCopy.c_str());
        }
        ~DeepString() { delete[] internal_; }
        char* str() const { return internal_; }
        const char* c_str()  const { return internal_; }
};

Und Sie können es verwenden als:

void aFunctionAPI(char* input);

//  other stuff

aFunctionAPI("Foo"); //this call is not safe. if the function modified the 
                     //literal string the program will crash
std::string myFoo("Foo");
aFunctionAPI(myFoo.c_str()); //this is not compiling
aFunctionAPI(const_cast<char*>(myFoo.c_str())); //this is not safe std::string 
                                                //implement reference counting and 
                                                //it may change the value of other
                                                //strings as well.
DeepString myDeepFoo(myFoo);
aFunctionAPI(myFoo.str()); //this is fine

Ich habe die Klasse aufgerufen, DeepStringweil sie eine tiefe und eindeutige Kopie (die DeepStringnicht kopierbar ist) einer vorhandenen Zeichenfolge erstellt.

Alessandro Teruzzi
quelle
3
Ich würde diese Namenskonvention vermeiden. c_str()wie von verwendet stdwird eine Abkürzung für "C-String" nicht "const String" und gibt str()immer ein std::basic_string, nicht char*(zum Beispiel std::stringstream::str())
bcrist
8
char* result = strcpy((char*)malloc(str.length()+1), str.c_str());
Cegprakash
quelle
1
sieht schick aus, ist aber schwer zu verstehen ... Einfach ist die beste IMO
Naeem A. Malik
4
strcpy (), malloc (), length () und c_str () sind Grundfunktionen, und daran ist nichts Schwieriges. Nur Speicher zuweisen und kopieren.
Cegprakash
5
Ja, die Funktionen sind grundlegend, aber Sie haben sie verdreht und gebogen, um wie eine Schüssel Spaghetti oder ein Liner Frankensteins Monster auszusehen :)
Naeem A. Malik
4
Ja, die Funktionen sind grundlegend, aber ... haben Sie sich erinnert, als Sie angefangen haben, sich mit einer Programmiersprache zu beschäftigen? Einige Zeilen mehr zu erklären und es wird einem Neuling wirklich helfen zu lernen, warum zum Beispiel anders oder besser als diese Antwort ist :)
Hastur
2
@cegprakash: Immer wenn es ein malloc () gibt, muss es auch ein freies () geben. Andernfalls verliert der Code Speicher, ebenso wie die Lösung in Ihrer Antwort. Das Zuweisen von Speicher, ohne zumindest auf die erforderliche Freigabe hinzuweisen, ist für solche Fragen eine schlechte Praxis.
Striezel
7

Sehen Sie sich das an:

string str1("stackoverflow");
const char * str2 = str1.c_str();

Beachten Sie jedoch, dass dies a zurückgibt const char *.

char *Verwenden strcpySie für a , um es in ein anderes charArray zu kopieren .

devsaw
quelle
23
Hallo, was Sie gepostet haben, wurde bereits mehrfach mit weiteren Details in anderen Antworten auf die 5 Jahre alte Frage gesagt. Es ist in Ordnung, ältere Fragen zu beantworten, aber nur, wenn Sie neue Informationen hinzufügen. Ansonsten ist es nur Lärm.
Mat
7
Persönlich schätze ich die Einfachheit.
TankorSmash
-4

Versuche dies

std::string s(reinterpret_cast<const char *>(Data), Size);
Anish
quelle