Casten von .c_str() klappt in RAD 6.0 nicht mehr
-
Hi.
Diese Zeile klappt
AnsiString Line = Line.sprintf("%s", Daten->Strings[j].c_str());
Diese Zeile klappt nicht mehr
UnicodeString Line = Line.sprintf("%s", Daten->Strings[j].c_str());
Aber TStringList ist UnicodeString und Line doch auch, warum klappt das dann nicht mehr?
-
~Caster schrieb:
Diese Zeile klappt nicht mehr
Was heißt das? Das is keine Fehlerbeschreibung!
-
Ups
Also das hier
AnsiString Line = Line.sprintf("%s", Daten->Strings[j].c_str());
compiliert, aber ich sehe in Line mit ShowMessage(Line) nur den ersten Buchstaben des Wortes.
Dies hier compiliert erst gar nicht und sagt
UnicodeString Line = Line.sprintf("%s", Daten->Strings[j].c_str());
[BCC32 Fehler] Unit1.cpp(144): E2034 Konvertierung von 'const char *' nach 'const wchar_t *' nicht möglich [BCC32 Fehler] Unit1.cpp(144): E2342 Keine Übereinstimmung des Typs beim Parameter 'format' ('const wchar_t *' erwartet, 'const char *' erhalten)
-
Ich nehme mal an das in den Projektoptionen _TCHAR entspricht wchar_t
eingestellt ist, deshalb kannst du auch nicht mehr bei UnicodeString c_str() verwenden sondern nur noch w_str() da der String ein WideString ist, also pro Zeichen 2 Byte benötigt, statt wie beim AnsiString 1 Byte.
-
Wo in den Projektoptionen stellt man dies denn ein? Also ein w_str() bewirkte leider keine Änderungen der Fehlermeldung.
-
Ich habe eben nur spasshalber die Zeile gekürzt
UnicodeString Line = Line.sprintf("123456");
und erhalte immernoch die Fehlermeldung. Liegt also wohl erstmal nicht am casten.
Das jetzt verstehe ich aber mal gar nicht.
-
Lösung ist
UnicodeString Line = Line.sprintf(L"123456");
Ein "L" reinsetzen. Was bedeutet das L und warum muss ich das reinsetzen?
-
Hallo
Ein normales String-Literal "123" wird vom Compiler als char* betrachtet. Dadurch wird der von dir beschriebene Fehler ausgelöst, denn der erste Parameter von sprintf verlangt nun ein wchar_t*.
Das L ist ein Zeichen für den Compiler, das er den folgenden String-Literal als wchar_t* interpretieren soll.bis bald
akari
-
~Caster schrieb:
Diese Zeile klappt
AnsiString Line = Line.sprintf("%s", Daten->Strings[j].c_str());
Schieres Glück. Wie kommst du darauf, man könne eine Variable mit sich selbst initialisieren?
Aktiviere mal CodeGuard, der macht dich auf so etwas aufmerksam.Richtig geht es so:
String Line = String ().sprintf (_D ("%s"), Daten->Strings[j].c_str ());
(_D() ist neu bei C++Builder 2009 und präfiziert das von dir bereits entdeckte L, mit dem ein Stringliteral explizit als wchar_t-Literal deklariert werden kann. Solltest du den Code unter älteren C++Builder-Versionen deklarieren müssen, so kannst du für diese einfach folgende Zeile in sysmac.h einfügen:
#define _D(x) x
Auf diese Weise kann man Code mit allen C++Builder-Versionen kompatibel halten. Wenn du nur C++Builder 2009 benutzt, kannst du aber auch das L-Präfix direkt benutzen.)
~Caster schrieb:
Also das hier
AnsiString Line = Line.sprintf("%s", Daten->Strings[j].c_str());
compiliert, aber ich sehe in Line mit ShowMessage(Line) nur den ersten Buchstaben des Wortes.
AnsiString ist ein char-String, entsprechend erwartet sprintf() auch 1-Byte-Argumente. Daten->Strings[j] ist aber ein UnicodeString, der aus wchar_t-Zeichen besteht, und diese sind zwei Bytes groß. Daß das überhaupt funktioniert, ist ebenfalls mehr oder weniger Glück, denn da die meisten Zeichen unseres Alphabets in ASCII enthalten sind, ist für diese Buchstaben das höherwertige Byte 0. Interpretiert man einen solchen String fälschlicherweise als char-String, endet er also schon nach dem ersten Buchstaben.
46 6F 6F 62 61 72 00 // "Foobar" 46 00 6F 00 6F 00 62 00 61 00 72 00 00 00 // L"Foobar" 46 00 // (const char*) L"Foobar"
-
Hi,
das gleiche Problem hatte ich auch. Irgendwie ist in RAD 6 c_str das gleiche wie wchar_t.
Aber ersetze mal c_str() durch t_str() dann dürfte es funktionieren!Gruß Hawk
-
Hawkxxx schrieb:
das gleiche Problem hatte ich auch. Irgendwie ist in RAD 6 c_str das gleiche wie wchar_t.
UnicodeString::c_str() gibt wchar_t* zurück, falls du das meinst.
Hawkxxx schrieb:
Aber ersetze mal c_str() durch t_str() dann dürfte es funktionieren!
Bloß nicht. t_str() ändert den Inhalt des Strings, ungeachtet dessen, ob es ein char- oder ein wchar_t-String ist, nach Ansi; in gewissen Situationen kann das Daten korrumpieren.
Ursprünglich tat auch UnicodeString::c_str() so etwas; seit Update 1 wird allerdings in jedem Fall wchar_t* zurückgegeben.
Mich ärgert nachhaltig, daß bei dieser Gelegenheit nicht auch gleich t_str() wieder entfernt wurdeWenn ein char-String benötigt wird, ist das der richtige Weg:
AnsiString (theString).c_str ()
-
audacia schrieb:
Richtig geht es so:
String Line = String ().sprintf (_D ("%s"), Daten->Strings[j].c_str ());
Oh, dann habe ich das bisher immer falsch gemacht.