Was ist die Verwendung der Funktion c_str In c ++

76

Ich habe gerade angefangen, C ++ zu lesen und festgestellt, dass C ++ reichhaltige Funktionen für die String-Manipulation hat, die C nicht hat. Ich lese diese Funktion und bin auf etwas gestoßen, c_str()von dem ich verstehe c_str, dass es eine Zeichenfolge konvertiert, die möglicherweise nullterminiert ist oder nicht, in eine nullterminierte Zeichenfolge. Ist das wahr?

Kann mir jemand ein Beispiel vorschlagen, damit ich die Verwendung der Funktion c_str verstehen kann ?

Amit Singh Tomar
quelle

Antworten:

90

c_strGibt a zurück const char*, das auf eine nullterminierte Zeichenfolge zeigt (dh eine Zeichenfolge im C-Stil). Dies ist nützlich, wenn Sie den "Inhalt" ¹ von std::stringan eine Funktion übergeben möchten, die erwartet, mit einer Zeichenfolge im C-Stil zu arbeiten.

Betrachten Sie beispielsweise diesen Code:

std::string str("Hello world!");
int pos1 = str.find_first_of('w');

int pos2 = strchr(str.c_str(), 'w') - str.c_str();

if (pos1 == pos2) {
    printf("Both ways give the same result.\n");
}

Sehen Sie es in Aktion .

Anmerkungen:

¹ Dies ist nicht ganz richtig, da ein std::string(im Gegensatz zu einer C-Zeichenfolge) das \0Zeichen enthalten kann . Wenn dies der Fall ist, wird der Code, der den Rückgabewert von empfängt, zu der c_str()Annahme verleitet, dass die Zeichenfolge kürzer ist als sie tatsächlich ist, da sie \0als Ende der Zeichenfolge interpretiert wird .

Jon
quelle
Sehr interessanter Punkt, den Sie in Notes gemacht haben: Was würde ich gerne wissen, wenn std :: string bereits enthalten ist \ 0, dann hängt c_str auch \ 0 am Ende des Strings an?
Amit Singh Tomar
2
@AmitSinghTomar: Ja, Sie haben also zwei Null-Bytes - eines, das rechtmäßig Teil der Zeichenfolge ist, und eines, das der Null-Terminator sein soll. Die Funktion im C-Stil, die den Zeiger empfängt, weiß dies jedoch nicht.
Jon
Hinweis: Einige C-APIs fragen nach zwei Argumenten ( char const*, size_t), wobei das zweite natürlich die Größe ist.
Matthieu M.
Dies funktioniert nicht: string str("0.85"); newVolume = _tstof((TCHAR*)str.c_str());Wie kann ich den TCHAR * argv [] -Eingang 0.85 in diesen konvertieren?
1
@YumYumYum, das Sie nicht std::stringzusammen mit TCHAR verwenden können. Der Sinn von TCHAR besteht darin, automatisch zwischen char / wchar zu wechseln, während dies std::stringnur in Bezug auf char funktioniert. Sie müssen eine geeignete Abstraktion verwenden oder einfach TCHAR überhaupt nicht verwenden und immer einen Unicode-Build ausführen.
Jon
55

In C ++ definieren Sie Ihre Zeichenfolgen als

std::string MyString;

anstatt

char MyString[20];.

Beim Schreiben von C ++ - Code stoßen Sie auf einige C-Funktionen, für die eine C-Zeichenfolge als Parameter erforderlich ist.
Wie unten:

void IAmACFunction(int abc, float bcd, const char * cstring);

Jetzt gibt es ein Problem. Sie arbeiten mit C ++ und verwenden std::stringZeichenfolgenvariablen. Diese C-Funktion fordert jedoch eine C-Zeichenfolge an. Wie konvertieren Sie Ihre std::stringin eine Standard-C-Zeichenfolge?

So was:

std::string MyString;
// ...
MyString = "Hello world!";
// ...
IAmACFunction(5, 2.45f, MyString.c_str());

Dafür ist da c_str().

Beachten Sie, dass für std::wstringZeichenfolgen c_str()a zurückgegeben wird const w_char *.

hkBattousai
quelle
8

Die meisten ALTEN c ++ - und c-Funktionen verwenden beim Umgang mit Zeichenfolgen const char*.
Mit STL und std::string, string.c_str()eingeführt aus umwandeln zu können , std::stringzu const char*.

Das heißt, wenn Sie versprechen, den Puffer nicht zu ändern, können Sie schreibgeschützte Zeichenfolgeninhalte verwenden. PROMISE = const char *

Daniel Mošmondor
quelle
@ Es gibt keine stl::string. Tatsächlich gibt es nicht einmal "STL" außer irgendwo in einem Museum.
Kerrek SB
6

c_str () konvertiert eine C ++ - Zeichenfolge in eine Zeichenfolge im C-Stil, die im Wesentlichen ein nullterminiertes Array von Bytes ist. Sie verwenden es, wenn Sie eine C ++ - Zeichenfolge an eine Funktion übergeben möchten, die eine Zeichenfolge im C-Stil erwartet (z. B. viele Funktionen der Win32-API, des POSIX-Stils usw.).

CadentOrange
quelle
3
Ich würde nicht "Konvertiten" sagen. Vielmehr "bietet" die Funktion "Zugriff" auf ein geeignetes schreibgeschütztes Zeichenarray - höchstwahrscheinlich ein Array, das bei der Implementierung von immer vorhanden war std::string.
Kerrek SB
5

Es wird verwendet, um die std::stringInteroperabilität mit C-Code zu gewährleisten, für den eine Null beendet werden muss char*.

pmr
quelle
5

In der C / C ++ - Programmierung gibt es zwei Arten von Zeichenfolgen: die C-Zeichenfolgen und die Standardzeichenfolgen. Mit dem <string>Header können wir die Standardzeichenfolgen verwenden. Andererseits sind die C-Zeichenfolgen nur ein Array normaler Zeichen. Um eine Standardzeichenfolge in eine C-Zeichenfolge zu konvertieren, verwenden wir diec_str() Funktion.

zum Beispiel

// a string to a C-style string conversion//

const char *cstr1 = str1.c_str();
cout<<"Operation: *cstr1 = str1.c_str()"<<endl;
cout<<"The C-style string c_str1 is: "<<cstr1<<endl;
cout<<"\nOperation: strlen(cstr1)"<<endl;
cout<<"The length of C-style string str1 = "<<strlen(cstr1)<<endl;

Und die Ausgabe wird sein,

Operation: *cstr1 = str1.c_str()
The C-style string c_str1 is: Testing the c_str 
Operation: strlen(cstr1)
The length of C-style string str1 = 17
Linkon Ruhul
quelle
1

Oh, ich muss hier meine eigene Auswahl hinzufügen. Sie werden diese verwenden, wenn Sie eine Zeichenfolge codieren / decodieren, die Sie zwischen zwei Programmen übertragen.

Nehmen wir an, Sie verwenden base64encode für ein Array in Python und möchten dieses dann in c ++ dekodieren. Sobald Sie die Zeichenfolge haben, dekodieren Sie in c ++ von base64decode. Alles, was Sie hier tun müssen, ist, um es wieder in das Array von float zu bringen

float arr[1024];
memcpy(arr, ur_string.c_str(), sizeof(float) * 1024);

Dies ist ziemlich häufig, nehme ich an.

Li haonan
quelle
Diese Art von Code ist nicht portabel (Endianness und Float-Format unter anderem)
Phil1970