2010-11-17 27 views
20

Powiel możliwe:
Convert std::string to const char* or char*Jak przekonwertować std :: string na const char *?

void Foo::bar(const std::string& foobar) { 
    // ... 
    const char* foobar2 = (char*)foobar; 
    // ... 
} 

To nie działa i pojawia się błąd podczas kompilacji o nieprawidłowym odlewu.

Czy istnieje inny sposób konwersji std::string na const char*?

+0

Dlaczego chcesz to zrobić? – GManNickG

+1

@GMan: istnieje wiele powodów, z których główny wywołuje funkcje w C API? –

+2

@Gman Ponieważ muszę przekazać zmienną foobar do funkcji inet_pton UDT, która pobiera tylko zmienne typu char *. –

Odpowiedz

10

std::string::c_str() pobiera wskaźnik const char* do tablicy znaków, która reprezentuje ciąg (zakończone znakiem NUL).

Nie należy manipulować danymi, na które wskazuje ten wskaźnik, więc jeśli trzeba to zrobić, skopiuj dane.

Podwójna edycja - robi to w bardziej C++ mody

Ponieważ jest ładniejszy w celu uniknięcia stosowania surowych wskaźników i tablic, gdzie to możliwe, można również uzyskać dane do programu std::vector<char>

#include <string> 
#include <vector> 

int main() 
{ 
    std::string str = "Hello"; 
    std::vector<char> cvec(str.begin(), str.end()); 

    // do stuff 
} 

Edycja to bardziej jak C ponieważ wykorzystuje surowe wskaźniki i wyraźnie przydziela MEM

#include <string> 
#include <cstring> 

int main() 
{ 
    std::string str = "Hello"; 
    char *cptr = new char[str.size()+1]; // +1 to account for \0 byte 
    std::strncpy(cptr, str.c_str(), str.size()); 

    // do stuff... 
    delete [] cptr; 
} 
+3

Użyj 'std :: vector', nigdy nie używaj' new T [] '. – GManNickG

+0

@GMan - dziękuję - zawsze domyślam się zachowania w stylu C, gdy pytanie pyta o wskaźniki, chociaż w C++ ziemi wiem, że powinienem trzymać się nauczania z materiałami na poziomie C++. – birryree

+0

Dlaczego 'strncpy', a nie' strcpy'? – i486

3
const char* foobar2 = foobar.c_str(); 

zauważy const. W przeciwnym razie musisz skopiować go do bufora znaków.

4

Otrzymasz wiele niepoprawnych odpowiedzi na temat str.c_str() tutaj. :) Podczas gdy c_str() jest rzeczywiście przydatny, należy pamiętać, że to nie będzie w rzeczywistości konwertować ciągu znaków na char*, ale raczej zwróci zawartość ciągu jako const char*. A to wielka różnica!

Co jest ważne, to wskaźnik, który uzyskasz od c_str(), jest ważny tylko tak długo, jak istnieje dany obiekt string. Więc byłoby to strasznie źle:

class Something { 
    const char* name; 
public: 
    Something(const std::string& pname) { 
     this->name = pname.c_str(); /* wrong! the pointer will go wrong as the object from the parameter ceases to exist */ 
    } 
}; 

więc jeśli chcesz nawróconego, na przykład: utworzyć nową wartość, która będzie niezależna od oryginalnego std::string, a następnie będziemy chcieli zrobić coś jak to:

char* convert(const std::string& str) { 
    char* result = new char[str.length()+1]; 
    strcpy(result,str.c_str()); 
    return result; 
} 

Ale nadal c_str() będzie zupełnie wystarczające dla ciebie w większości przypadków.Po prostu staraj się myśleć w kategoriach czasu życia przedmiotów.

+2

Powinien mieć wartość "str.length() + 1", ponieważ długość nie liczy bajtu zerowego. – birryree

+2

Użyj 'std :: vector', nigdy nie używaj' new T [] '. – GManNickG

+0

@birryree - Właśnie tak! Dzięki. – Kos

Powiązane problemy