AnsiString Methode c_str() gibt wchar_t zurück - warum?



  • Nach dem Update auf eine (sehr viel) neuere C-Builderversion gibt c_str() einen Zeiger auf wchar_t zurück, sollte aber laut Embarcadero-Wiki eigentlich einen Zeiger auf char bringen - warum?
    Wie komme ich zu einem altertümlichen char-Zeiger (notfalls auch multibyte)?
    Ich möchte meine riesigen Datenfelder nicht mit wchar verdoppeln.

    Vielen Dank.

    Bernhard



  • Projekt - Optionen - Verzeichnisse und Bedingungen

    Eintrag "_TCHAR entspricht" von wchar_t nach char ändern.



  • Danke für den Tip, das hatte ich schon geändert - leider bisher ohne Erfolg.

    Gruß Bernhard



  • Welche C++Builder-Version ist das?

    Außerdem glaube ich kaum, daß AnsiString::c_str() einen wchar_t* zurückgibt. Eher kann es sein, daß dein Code Ausdrücke enthält, die plötzlich nicht mehr vom Typ AnsiString, sondern vom Typ UnicodeString sind (praktisches Beispiel: MyForm->Caption ).

    Edit: char* -> wchar_t*



  • Der Sprung war von C-Builder3 zu C-Builder XE.

    MyForm->Caption ist ein prima Beispiel. Unter BCB3 war es ein AnsiString, mit der Methode c_str() bekam ich einen Zeiger auf char.
    Unter BCBXE bekomme ich (laut Fehlermeldung) einen Zeiger auf wchar_t.
    Daß es sich um einen UnicodeString handelt, hat mich jetzt überrascht, da unter UnicodeString die Methode c_str() eigentlich gar nicht aufgeführt ist. Da war ich auf dem falschen Pferd.

    Ist es möglich aus einem UnicodeString den Zeiger auf ein Multibyte-String zu bekommen, oder muß ich mit wctomb() konvertieren?

    Vielen Dank für Eure Hilfe

    Gruß Bernhard



  • antiriad schrieb:

    Ist es möglich aus einem UnicodeString den Zeiger auf ein Multibyte-String zu bekommen

    AnsiString (MyForm->Caption).c_str ()
    

    Allerdings ist zu beachten, daß der Zeiger nur bis zum Ende des Statements gültig ist. Also das hier geht:

    FILE* f = std::fopen (AnsiString (MyEdit->Text).c_str (), "r");
    

    Das hier aber nicht:

    const char* p = AnsiString (MyEdit->Text).c_str ();
    FILE* f = std::fopen (p, "r");
    

    Mit dem abschließenden Semikolon ist die Lebensdauer des temporären AnsiString -Objekts zuende, und es wird freigegeben, so daß p in freigegebenen Speicher zeigt. Der Zugriff funktioniert zwar manchmal, ist aber undefiniert, das hängt letztlich von den Entscheidungen der Speicherverwaltung ab. Und wie das eben so ist, geht es bei all deinen Tests gut, aber wenn du das Programm gerade deinem Chef vorführst, gibt es eine Zugriffsverletzung.

    Und in diesem konkreten Beispiel wäre es natürlich besser, wenn du den String gar nicht konvertierst:

    FILE* f = std::_wfopen (MyEdit->Text.c_str (), "r"):
    

    Dann unterstützt dein Programm nämlich auch Unicode-Dateinamen. Jede Umwandlung mit AnsiString() ist verlustbehaftet.



  • antiriad schrieb:

    Der Sprung war von C-Builder3 zu C-Builder XE.

    MyForm->Caption ist ein prima Beispiel. Unter BCB3 war es ein AnsiString, mit der Methode c_str() bekam ich einen Zeiger auf char.

    Sämtliche Strings in der VCL, also Caption- und Text-Properties sind KEINE AnsiStrings mehr, sondern UnicodeStrings und bei denen liefert c_str() einen wchar_t zurück. Da musst Du wohl oder übel ran. Den Typ AnsiString gibt es auch noch, aber nicht mehr als Datentyp für Eigenschaften bei den Komponenten.
    Deswegen meine nicht ganz richtige erste Antwort.



  • Vielen Dank für Eure Hilfe, vor allem auch für den Hinweis über den Fallstrick der Gültigkeitsdauer.
    Als Nichtinformatiker tappe ich grundsätzlich in solche Fallen, und suche tagelang.

    Gruß Bernhard


Log in to reply