Autor Wątek: std::string do char*  (Przeczytany 3877 razy)

Offline comrade

  • Użytkownik
    • AlertGrid

# Styczeń 16, 2006, 18:21:30
Może to lamerskie pytanie ale jak skonwertować std::string do char*, np zeby przekazac do funkcji ktora w parametrze oczekuje char* ?

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Hadrian W.

  • Użytkownik
    • Homepage

# Styczeń 16, 2006, 18:24:10
std::string dupa;
char *cos;
cos=dupa.c_str();

Offline Yazilim

  • Użytkownik

# Styczeń 18, 2006, 08:39:24
std::string dupa;
char *cos;
cos=dupa.c_str();
Ja bym jeszcze dodał, że c_str() zwraca const char *, a nie char *, czyli przy użyciu zwroconego wskaźnika nie można modyfikować tekstu.

Pozdr,
Yazilim.

bies

  • Gość
# Styczeń 18, 2006, 13:41:27
Ja by dodał nawet, że kod Q8 jest błędny. :D Jeśli potrzebujemy char * ze std::string to należy użyć jakiegoś pośrednika, np. std::vector<char>, przykład:std::string test = "Simple test";
std::vector<char> test_vec(test.begin(), test.end());
std::strncpy(&test_vec[0], "SIMPLE", std::strlen("SIMPLE"));
std::string modified_test(test_vec.begin(), test_vec.end());
// ^^^^ Ew. nie do test_vec.end() a do pierwszego wystąpienia '\0', hint: find.
std::cout << modified_test << std::endl;

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Styczeń 18, 2006, 15:16:26
Cytuj
Ja by dodał nawet, że kod Q8 jest błędny.
Ja bym dodał, że Twój jest nawet gorszy. ;) Używanie c_str() jest OK, o ile robimy to z głową, czyli:
- nie zmieniamy nic w zwróconym tekście
- nie zmieniamy nic w wyjściowym obiekcie podczas używania zwróconego wskaźnika
- nie używamy wskaźnika po modyfikacji obiektu (zwłaszcza jego zniszczeniu)

Trzeba trochę uważać, ale do wywoływania funkcji wymagających (const char *) jako parametru (np. printf, fopen, itp.) się to nadaje. :)

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Styczeń 18, 2006, 15:32:51
Cytuj
Tam jest napisane char* a nie const char*
A to zwracam honor - moje niedopatrzenie. :) Swoją drogą, wywoływanie strncpy na std:vector bardziej przyprawia mnie o dreszcze niż rzutowanie const char * na char *, gdzie być może ktoś po prostu zapomniał dopisać "const" w deklaracji funkcji, a funkcja i tak podanego jej tekstu nie zmienia.

Jeżeli chodzi o przekazywanie char * do funkcji w celu odczytania czegoś, to myślę, że dobrym rozwiązaniem jest po prostu użycie tablicy charów.
char buff[20];
sprintf(buff,"%+8.3f",value);
std::string my_string = buff;
Oczywiście trzeba zadbać o to, żeby bufor był odpowiednio duży, ale tego problemu się przy zwracaniu łańcuchów przez char* nie uniknie. :)

bies

  • Gość
# Styczeń 18, 2006, 15:42:55
Jeżeli chodzi o przekazywanie char * do funkcji w celu odczytania czegoś, to myślę, że dobrym rozwiązaniem jest po prostu użycie tablicy charów.
char buff[20];
sprintf(buff,"%+8.3f",value);
std::string my_string = buff;
Oczywiście trzeba zadbać o to, żeby bufor był odpowiednio duży, ale tego problemu się przy zwracaniu łańcuchów przez char* nie uniknie. :)
A czemu np nie tak ? :

std::string a = boost::str( boost::format( "%8.3f" ) % 10.234453 );
;) i nie ma niebezpieczenstwa rozwalenia buforkow (nadpisania)
« Ostatnia zmiana: Styczeń 18, 2006, 15:45:04 wysłana przez st3tc »

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Styczeń 18, 2006, 16:53:37
Cytuj
A czemu np nie tak ? :
- najpierw trzeba znać boosta :P
- no i wypada mieć go zainstalowanego (co dodaje kolejne powiązanie, jeżeli wypuszczesz źródła)
- pozatym to, co napisałeś, to chyba nie jest dokładnie to samo ("%+8.3f" zawsze drukuje znak przed liczbą)

Ale ogólnie to będę musiał się kiedyś z boostem zapoznać. :)


EDIT: Zapomniałem o najważniejszym: nie tak, ponieważ to jest tylko przykład. Pytanie dotyczyło uzywania char * razem z std::string, a nie do wszystkiego mogą istnieć alternatywne rozwiązania. sprintf to był tylko przykład funkcji, która zwraca wynik przez char *. :)
« Ostatnia zmiana: Styczeń 18, 2006, 16:55:54 wysłana przez Krzysiek K. »

bies

  • Gość
# Styczeń 18, 2006, 16:57:25
- pozatym to, co napisałeś, to chyba nie jest dokładnie to samo ("%+8.3f" zawsze drukuje znak przed liczbą)

blah ...

int main(int argc, char* argv[])
{
std::cout << boost::format( "%+8.3f" ) % -10.234453 << std::endl;
return 0;
}
;)
« Ostatnia zmiana: Styczeń 18, 2006, 17:01:10 wysłana przez st3tc »

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Styczeń 18, 2006, 17:09:56
Cytuj
blah ...
Przeczytaj edita mojego posta, jeżeli jeszcze nie przeczytałeś - w zasadzie to nie chodziło o sprintf, ale jakąkolwiek funkcję przyjmującą char * jako parametr. Na przykład plugin VST w ten sposób przekazuje swoją nazwę i nie da się tego obejść pisząc hosta VST, gdyż taki jest standard. :)

Offline xeryph

  • Użytkownik

# Styczeń 18, 2006, 23:54:06
czego nie widzicie najprostrzego i najlatwiejszego
(BRUTE !!!) rozwiazania :)

std::string tekst = "to jest tekst";
char* ptr;

ptr = const_cast<char*> (tekst.c_str());
ptr[3] = 'X';
        // "to Xest tekst" :)


bies

  • Gość
# Styczeń 19, 2006, 00:57:32
Standard zabrania. 21.3.6.2: ,,The program shall not alter any of the values stored in the array [gdzie <<array>> oznacza tablicę do której wskaźnik zwraca c_str()]''.

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Styczeń 19, 2006, 08:58:19
I znowu zrobiła się zażarta dyskusja z niczego :). Bufora otrzymanego przez c_str() oczywiście nie należy modyfikować, a jeśli musimy w nim coś zmienić, to trzeba skopiować zawartość wskazywaną przez c_str do innego bufora, typu char*. Proste.

Offline Yazilim

  • Użytkownik

# Styczeń 19, 2006, 11:54:25
I znowu zrobiła się zażarta dyskusja z niczego :).
No w sumie to nie jest tak źle z takimi dyskusjami, zawsze się można przypadkiem czegoś nowego dowiedzieć albo nauczyć, a to już jest coś :)

Pozdr,
Yazilim.