Konwersja tekstu z Edit na char *

dział ogólny

Konwersja tekstu z Edit na char *

Postprzez Bert1223 » poniedziałek, 14 grudnia 2009, 23:46

Na chwile obecną używam takiego kodu z marnym efektem.
Chce przeprowadzić konwersję z pola Edit na char *

kod
Kod: Zaznacz cały
char * bufor;
sprintf(bufor, "%s", EName->Text);
FormManu->Lan[i].setName(bufor);


funkcja setName()
Kod: Zaznacz cały
void setName(char * set_name)
{
   strcpy(name, set_name);
}


W efekcie zamiast np. "Warszawa" dostaję "W"
Avatar użytkownika
Bert1223
Bladawiec
Bladawiec
 
Posty: 45
Dołączył(a): czwartek, 15 października 2009, 02:41
Podziękował : 6
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: Konwersja tekstu z Edit na char *

Postprzez Witold » poniedziałek, 14 grudnia 2009, 23:53

Kod: Zaznacz cały
FormManu->Lan[i].setName(EName->Text.c_str());
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: Konwersja tekstu z Edit na char *

Postprzez Bert1223 » wtorek, 15 grudnia 2009, 10:35

Niestety tak też próbowałem, z tą różnicą, że teraz wcale program nie rusza i zwraca komunikat: 'Cannot convert 'wchar_t *' to 'char *', 'wanted 'char *', got 'wchar_t *'
Avatar użytkownika
Bert1223
Bladawiec
Bladawiec
 
Posty: 45
Dołączył(a): czwartek, 15 października 2009, 02:41
Podziękował : 6
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: Konwersja tekstu z Edit na char *

Postprzez Cyfrowy Baron » wtorek, 15 grudnia 2009, 11:56

Dzieje się tak dlatego, że używasz środowiska C++Builder 2009 lub C++Builder 2010, gdybyś uzupełnił profil użytkownika forum o typ używanego środowiska i systemu operacyjnego odpowiedź byłaby precyzyjna.

Wymienione wyżej środowiska różnią się tym od wcześniejszych wersji że zamiast typu AnsiString domyślnie używają typu UniceString. Było o tym na tym forum i podane było już wielokrotnie rozwiązanie problemu konwersji, ale Ty idąc na łatwiznę nie zamierzasz niczego szukać, tylko czekasz aż zostanie poda gotowe rozwiązanie. No, ale niestety, niektórych myślenie boli...

Jeżeli użycie operatora c_str() nie rozwiązuje problemu to możliwe, że należy posłużyć się operatorem t_str(), jednak rozwiązanie problemy wymaga określenia typu zmiennej jakiej oczekuje funkcja setName(???).

FormManu->Lan[i].setName(jakiego_typu_wymaga_funkcja_tutaj? );
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Konwersja tekstu z Edit na char *

Postprzez polymorphism » wtorek, 15 grudnia 2009, 12:33

Cyfrowy Baron napisał(a):FormManu->Lan[i].setName(jakiego_typu_wymaga_funkcja_tutaj? );

Nie czytasz dokładnie. Bert1223 w pierwszym poście podał definicję metody setName, i widać, że chodzi o char*. Nawet treść błędu na to wskazuje:

    Cannot convert 'wchar_t *' to 'char *', 'wanted 'char *', got 'wchar_t *

p.s. c_str/t_str nie jest operatorem, jest metodą.




Bert1223 napisał(a):
Kod: Zaznacz cały
char * bufor;
sprintf(bufor, "%s", EName->Text);
FormManu->Lan[i].setName(bufor);

Poza tym, że ten kod jest bez sensu, ma poważny błąd - bufor nie wskazuje na żadną pamięć, do której funkcja sprintf mogłaby wpisać zawartość. Następna rzecz to to, że w setName korzystasz z strcpy do kopiowania stringa, czyli tak jak powinno się robić, ale w kodzie, który zacytowałem używasz sprintf do tego samego celu. Why?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Konwersja tekstu z Edit na char *

Postprzez Cyfrowy Baron » wtorek, 15 grudnia 2009, 13:26

Kod: Zaznacz cały
FormManu->Lan[i].setName(EName->Text.t_str());


trzeba użyć metody: t_str()
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Konwersja tekstu z Edit na char *

Postprzez Bert1223 » wtorek, 15 grudnia 2009, 20:11

Dodanie .t_str(), pozornie działa, wywala się przy treści poniżej 3 znaków, efektem są np 2 kwadraty lub przy kombinacji znaków np, przy Leszczyny efektem jest Leszczyn$
Avatar użytkownika
Bert1223
Bladawiec
Bladawiec
 
Posty: 45
Dołączył(a): czwartek, 15 października 2009, 02:41
Podziękował : 6
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: Konwersja tekstu z Edit na char *

Postprzez Cyfrowy Baron » środa, 16 grudnia 2009, 08:55

Wina nie leży w metodzie t_str(), tylko w czym innym, być może w funkcji setName. t_str() po prostu konwertuje tekst UnicodeString na char i długość łańcucha znaków nie ma tutaj znaczenia, jeżeli nie przekracza pojemności zmiennej.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Konwersja tekstu z Edit na char *

Postprzez polymorphism » środa, 16 grudnia 2009, 13:20

Jeśli dobrze zrozumiałem ten opis, to panowie z borlanda nieźle pojechali przy robieniu metody t_str :D

W zasadzie użycie t_str tam, gdzie wymagane jest zawsze char*, jest ryzykowne. To, co zwróci ta metoda, uzależnione jest od trybu kompilacji (litera 't' -> TCHAR, LPTSTR, t_str itd.). Może to być const char* lub const wchar_t*.


Zakładając, że AnsiString faktycznie nim jest, i że przyjmuje w konstruktorze UnicodeString'a, takie coś powinno przejść, niezależnie od trybu kompilacji:
Kod: Zaznacz cały
FormManu->Lan[i].setName(AnsiString(EName->Text).c_str());
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Konwersja tekstu z Edit na char *

Postprzez Cyfrowy Baron » środa, 16 grudnia 2009, 15:51

Zakładając, że AnsiString faktycznie nim jest, i że przyjmuje w konstruktorze UnicodeString'a, takie coś powinno przejść, niezależnie od trybu kompilacji:


We wcześniejszych wersjach środowiska zawsze domyślnie stosowany był typ AnsiString, zadeklarowanie zmiennej typu String odnosiło się do AnsiString. W nowszych wersjach (sprawdzałem, więc wiem) domyślnie stosowany jest typ UniceodeString i np. zadeklarowanie typu String odnosi się już nie do AnsiString lecz do UnicodeSring.

Przy tamim zapisie:

Kod: Zaznacz cały
FormManu->Lan[i].setName(AnsiString(EName->Text).c_str());


w środowiskach C++Builder 2009 i 2010 dokonujesz najpierw konwersji UnicodeString, gdyż właściwość Text obiektu typu TEdit jest typu UnicodeString, a potem dokonujesz konwersji na char. To oczywiście zadziała, lecz mamy tutaj podwójną konwersję.
Testowałem metodę t_str() w odniesieniu do różnych przypadków i nie pojawił mi się żaden błąd konwersji.

Można zmienić sposób mapowania TCHAR w menu: Project > Options > Directories and Conditionals w tabeli po prawej stronie wybieramy wiersz _TCHAR map to i zamiast wartości char ustawiamy tam wchar_t. Po tej zmianie wszystkie funkcje, metody itp. zamiast wartości typu char będą oczekiwały wartości typu wchar_t, ale to tylko bardziej komplikuje sytuację.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Konwersja tekstu z Edit na char *

Postprzez polymorphism » środa, 16 grudnia 2009, 16:33

We wcześniejszych wersjach środowiska zawsze domyślnie stosowany był typ AnsiString, zadeklarowanie zmiennej typu String odnosiło się do AnsiString. W nowszych wersjach (sprawdzałem, więc wiem) domyślnie stosowany jest typ UniceodeString i np. zadeklarowanie typu String odnosi się już nie do AnsiString lecz do UnicodeSring.

Nie w tym rzecz. Chodzi o to, jak metoda t_str działa. Według opisu, do którego podałem link, metoda ta zmienia na stałe wewnętrzną zawartość UnicodeStringa z unikodu na ansi:

    the System::UnicodeString::t_str method returns const char* (instead of const wchar_t*), by narrowing the wide data of the UnicodeString instance. This behavior can be unexpected, because code might not expect a call to t_str() to corrupt the underlying data.

Innymi słowy, wywołanie t_str "psuje" zawartość stringa. I w sumie by się zgadzało, bo niby na co wskazuje wskaźnik, który zwraca t_str? Nie może po prostu zwrócić wskaźnika na jakąś nowo przydzieloną pamięć, przecież ktoś musi ją później zwolnić. W wx-ach na przykład tego typu metody zwracają specjalny obiekt, który pełni rolę bufora. Nie rozumiem dlaczego w VCL-u nie rozwiązano tego w ten sposób, zwracając chociażby AnsiStringa...

To oczywiście zadziała, lecz mamy tutaj podwójną konwersję.

Nie bardzo rozumiem, skąd ta podwójna konwersja? Przecież podając AnsiStringowi UnicodeStringa dokonuję konwersji unikod -> ansi.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Konwersja tekstu z Edit na char *

Postprzez Cyfrowy Baron » środa, 16 grudnia 2009, 19:15

Nie bardzo rozumiem, skąd ta podwójna konwersja? Przecież podając AnsiStringowi UnicodeStringa dokonuję konwersji unikod -> ansi.

AnsiString(EName->Text).c_str()


Najpierw konwertujesz UnicodeString (EName->Text) na AnsiString, a potem AnsiString na char (c_str()).
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Konwersja tekstu z Edit na char *

Postprzez polymorphism » środa, 16 grudnia 2009, 19:49

Konwersja AnsiString -> c-string (c_str) jest umowna, wszak nie ma tu czego konwertować. W praktyce sprowadza się to do zwrócenia wskaźnika na dane, które AnsiString przechowuje.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 1 gość