Antworten:
Es wird nicht automatisch konvertiert (Gott sei Dank). Sie müssen die Methode verwenden c_str()
, um die C-String-Version zu erhalten.
std::string str = "string";
const char *cstr = str.c_str();
Beachten Sie, dass es a zurückgibt const char *
; Sie dürfen die von zurückgegebene Zeichenfolge im C-Stil nicht ändern c_str()
. Wenn Sie es verarbeiten möchten, müssen Sie es zuerst kopieren:
std::string str = "string";
char *cstr = new char[str.length() + 1];
strcpy(cstr, str.c_str());
// do stuff
delete [] cstr;
Oder in modernem C ++:
std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);
vector
wurde genau als Wrapper für dynamische Arrays erfunden, daher scheint es im besten Fall eine verpasste Gelegenheit zu sein und im schlimmsten Fall gegen den Geist von C ++ zu verstoßen.
std::string
würde sich automatisch konvertieren) und dann erkläre ich anhand eines kurzen Codebeispiels, was er verwenden sollte. Wenn ich nach vorne denke, erkläre ich auch einige Nebenwirkungen der Verwendung dieser Funktion, von denen eine darin besteht, dass Sie die von zurückgegebene Zeichenfolge möglicherweise nicht bearbeiten c_str()
. Sie sehen meine kurzen Beispiele fälschlicherweise als echten Code zur Problemlösung, was es nicht ist.
std::vector<char>
).
Weitere Details hier und hier, aber Sie können verwenden
string str = "some string" ;
char *cstr = &str[0];
Wenn ich eine veränderbare Rohkopie des Inhalts eines C ++ - Strings benötigen würde, würde ich Folgendes tun:
std::string str = "string";
char* chr = strdup(str.c_str());
und später:
free(chr);
Warum spiele ich nicht wie jeder andere mit std :: vector oder new []? Denn wenn ich eine veränderbare rohe char * -String-Zeichenfolge im C-Stil benötige, möchte ich C-Code aufrufen, der die Zeichenfolge ändert, und C-Code die Zuordnung von Sachen mit free () und die Zuweisung von malloc () aufheben (strdup verwendet malloc) . Wenn ich also meine Rohzeichenfolge an eine in C geschriebene Funktion X übergebe , hat dies möglicherweise eine Einschränkung für das Argument, dass sie auf dem Heap zugewiesen werden muss (z. B. wenn die Funktion möglicherweise Realloc für den Parameter aufrufen möchte). Es ist jedoch höchst unwahrscheinlich, dass ein Argument erwartet wird, das mit (einigen vom Benutzer neu definierten) neuen [] zugewiesen wird!
strdup
kommt.
(Diese Antwort gilt nur für C ++ 98.)
Bitte verwenden Sie keine rohen char*
.
std::string str = "string";
std::vector<char> chars(str.c_str(), str.c_str() + str.size() + 1u);
// use &chars[0] as a char*
vector<char>(str.c_str(), str.c_str() + str.size() + 1)
, ohne den Zeichenzeiger einem temporären zuzuweisen.
std::basic_string<>::c_str()
ist gültig, bis der string
geändert oder zerstört wird. Dies bedeutet auch, dass bei nachfolgenden Aufrufen derselbe Wert zurückgegeben wird, solange der string
nicht geändert wird.
vector
diese Weise wird weder Geschwindigkeit noch Platz benötigt . Und wenn man schreiben würde Ausnahme sicher ohne RAII Mechanismus Code (dh unter Verwendung von rohen Zeigern), würde die Komplexität des Codes viel höher sein als dieser einfache Einzeiler.
vector
der viel Aufwand und Komplexität mit sich bringt. Wenn Sie ein veränderbares Zeichenarray benötigen, ist ein Zeichenvektor tatsächlich der ideale C ++ - Wrapper. Wenn Ihre Anforderung tatsächlich nur einen const-char-Zeiger erfordert, verwenden c_str()
Sie einfach und Sie sind fertig.
Wenn Sie nur eine Zeichenfolge im C-Stil möchten, die denselben Inhalt darstellt:
char const* ca = str.c_str();
Wenn Sie eine Zeichenfolge im C-Stil mit neuem Inhalt möchten , besteht eine Möglichkeit (da Sie die Zeichenfolgengröße zur Kompilierungszeit nicht kennen) in der dynamischen Zuweisung:
char* ca = new char[str.size()+1];
std::copy(str.begin(), str.end(), ca);
ca[str.size()] = '\0';
Vergiss delete[]
es später nicht.
Wenn Sie stattdessen ein statisch zugewiesenes Array mit begrenzter Länge möchten:
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
Konvertiert nicht implizit in diese Typen aus dem einfachen Grund, dass dies normalerweise ein Designgeruch ist. Stellen Sie sicher, dass Sie es wirklich brauchen.
Wenn Sie definitiv eine brauchen char*
, ist der beste Weg wahrscheinlich:
vector<char> v(str.begin(), str.end());
char* ca = &v[0]; // pointer to start of vector
&str.front(), &str.back()
(die in C ++ 03 nicht vorhanden sind) statt der häufigeren str.begin()
und str.end()
?
str.begin()
ist mit oder sogar std::begin(str)
iteratorartig? Ich glaube nicht, dass string
es eine Verpflichtung gibt, in zusammenhängender Erinnerung zu sein vector
, oder?
&back() + 1
, nicht&back()
Dies wäre besser als Kommentar zu Bobobobos Antwort, aber ich habe keinen Repräsentanten dafür. Es erreicht das Gleiche, aber mit besseren Praktiken.
Obwohl die anderen Antworten nützlich sind, wenn Sie jemals konvertieren müssen , std::string
um char*
explizit ohne const, const_cast
ist dein Freund.
std::string str = "string";
char* chr = const_cast<char*>(str.c_str());
Beachten Sie, dass dies nicht eine Kopie der Daten geben; Sie erhalten einen Zeiger auf die Zeichenfolge. Wenn Sie also ein Element von chr
ändern, ändern Sie es str
.
Um streng pedantisch zu sein, können Sie "einen std :: string nicht in einen char * - oder char [] -Datentyp konvertieren".
Wie die anderen Antworten gezeigt haben, können Sie den Inhalt des std :: string in ein char-Array kopieren oder ein const char * für den Inhalt des std :: string erstellen, damit Sie in einem "C-Stil" darauf zugreifen können. .
Wenn Sie versuchen, den Inhalt des std :: string zu ändern, verfügt der std :: string-Typ über alle Methoden, um alles zu tun, was Sie möglicherweise tun müssen.
Wenn Sie versuchen, es an eine Funktion zu übergeben, die ein Zeichen * akzeptiert, gibt es std :: string :: c_str ().
Der Vollständigkeit halber nicht vergessen std::string::copy()
.
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
str.copy(chrs, MAX);
std::string::copy()
beendet NUL nicht. Wenn Sie einen NUL-Terminator für die Verwendung in C-String-Funktionen sicherstellen müssen:
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
memset(chrs, '\0', MAX);
str.copy(chrs, MAX-1);
Hier ist eine weitere robuste Version von 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
if (str[str.length()-1] != 0) str.push_back(0)
Konvertierung im OOP-Stil
converter.hpp
class StringConverter {
public: static char * strToChar(std::string str);
};
converter.cpp
char * StringConverter::strToChar(std::string str)
{
return (char*)str.c_str();
}
Verwendungszweck
StringConverter::strToChar("converted string")
char* result = strcpy((char*)malloc(str.length()+1), str.c_str());
Alternativ können Sie Vektoren verwenden, um ein beschreibbares Zeichen * zu erhalten, wie unten gezeigt.
//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
Um eine const char *
von einem zu erhalten, std::string
verwenden Sie die c_str()
Member-Funktion:
std::string str = "string";
const char* chr = str.c_str();
Um eine Nicht-Konstante char *
von einer zu erhalten std::string
, können Sie die Elementfunktion verwenden, die data()
seit C ++ 17 einen Nicht-Konstanten-Zeiger zurückgibt:
std::string str = "string";
char* chr = str.data();
Bei älteren Versionen der Sprache können Sie die Zeichenfolge mithilfe der Bereichskonstruktion in einen Vektor kopieren, aus dem ein nicht konstanter Zeiger abgerufen werden kann:
std::string str = "string";
std::vector<char> str_copy(str.c_str(), str.c_str() + str.size() + 1);
char* chr = str_copy.data();
Beachten Sie jedoch, dass Sie dadurch die darin enthaltene Zeichenfolge nicht ändern str
können. Nur die Daten der Kopie können auf diese Weise geändert werden. Beachten Sie, dass es in älteren Versionen der Sprache besonders wichtig ist, diese zu verwenden c_str()
, da damals std::string
nicht garantiert wurde, dass sie bis c_str()
zum Aufruf mit Null beendet wird .
Dies wird auch funktionieren
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;
c_str
Wahnsinn eher vollständig vermeiden .