Jonglieren mit versch. Stringtypen



  • Heyho!

    Ich habe mal eine recht grundsätzliche Frage, bin noch nicht so erfahren in C++.

    Ich habe eine Funktion, die einen char oder char * zurückgibt. Dieser String hat eine unbekannte Länge, das heißt eine geeignete Deklarierung einer entsprechenden Variable wird schwierig, da ich das Array sehr groß machen muss, damit ich sicher gehen kann, dass die Wahrscheinlichkeit, dass die Größe ausreicht nahezu 100% ist.
    Nun muss ich diesen String bearbeiten, z.B. einen Teil entfernen oder einen anderen String anhängen. Das fällt mir mit einem char im Moment auch eher schwer, sodass ich ihn erst in einen CString umwandel und dann z.B. Append() benutze. Einige Funktionen wollen nun einen LPCTSTR oder LPCWSTR was wieder Probleme macht, da wieder umwandeln (glaube LPCTSTR ging automatisch von CString). Aber dann gibt es wieder funktionen, die den String wieder als char oder char * haben wollen. Das ganze hin und her konvertieren des gleichen String kanns doch irgendwie nicht sein, denn ich bekomme ja auch jedesmal das Problem mit der größe des char Arrays oder muss mit new und delete herumhantieren.

    Deswegen meine Frage jetzt, welchen (scheinbar wichtigen) Aspekt von C++ habe ich noch nicht ausreichen kapiert? Wie geht das ganze einfacher und eleganter?
    Obige Beschreibung stammt natürlich aus einem konkreten Problem, dass ich zur Zeit habe und gerne gelöst wüsste, aber denke soetwas wird mir noch öfter begegnen, deswegen habe ich die Frage mal versucht etwas allgemeiner zu fassen.



  • PinguPinguin schrieb:

    Deswegen meine Frage jetzt, welchen (scheinbar wichtigen) Aspekt von C++ habe ich noch nicht ausreichen kapiert? Wie geht das ganze einfacher und eleganter?

    Und wie.

    C++ besitzt die Klasse std::string . Diese eignet sich gut für Verwaltung von Zeichenketten. Du kannst bequem Buchstaben anhängen, durchiterieren, suchen und so weiter. Für die Umwandlung in const char* gibt es die Methode c_str() . Du brauchst auch nicht riesigen Speicherplatz zu verschwenden, da std::string dynamisch gerade so viel Speicher anfordert, wie benötigt wird.

    Mehr Informationen erhältst du unter der guten C++-Referenz www.cplusplus.com ;).



  • PinguPinguin schrieb:

    Das ganze hin und her konvertieren des gleichen String kanns doch irgendwie nicht sein, denn ich bekomme ja auch jedesmal das Problem mit der größe des char Arrays oder muss mit new und delete herumhantieren.

    Vielleicht zur Historie von C++: Auch wenn die Sprache inzwischen etwa 30 Jahre alt ist, ist erst mit dem C++ Standard von 1998 ein Stringtyp eingeführt wurden - dies ist einer der gründe für die verschiedenen Stringtypen, wenn gleich du zudem nicht nur mit C++ sondern auch C hantierst (LPCTSTR ist eine typische Windows API Typbezeichnung, und C kennt Stringtypen an sich garnicht, wenn wir mal von irgendwie gearteten Charakterarrays absehen).

    Das nächste Problem warum man in C++ teilweise auch aktuell mit den sogenannten C-Strings hantieren muß: C++ ist mit Ausnahme des C-Anteiles eigentlich nicht binärkompatibel. Sprich: Wenn man nicht gerade sich auf genau eine Compilerversion festlegen will, muss man binär vorliegende Bibiothekten (wie z.b. DLL's u.a. unter Windows) mit einer C kompatiblen Schnittstelle versehen.

    PinguPinguin schrieb:

    Deswegen meine Frage jetzt, welchen (scheinbar wichtigen) Aspekt von C++ habe ich noch nicht ausreichen kapiert? Wie geht das ganze einfacher und eleganter?

    Da du scheinbar mit der Windows API, der MFC (einer in die Jahre gekommenen Bibliothek, die vor dem Standard entstanden ist) hin und her jonglieren willst, wirst du dich wohl dadurch beisen müssen. Die von dir angesprochenen Umwandlungen sind aber auch Abhängig von den Bibliotheken, so das du wohl am ehesten in dem MFC-Unterforum erfolg haben solltest.

    Der eigentliche C++ Stringtyp wurde von dir auch garnicht angesprochen (std::string oder std::wstring) so das es sich auch nicht auf den AnsiC++ Standard bezieht. Normalerweise sollte aber mindestens CString einige Konvertierungen anbieten, da du aber ggf. die Problematik der konvertierung von Unicode und Ansistrings haben könntest, wäre die genaue Übersicht aller von dir verwendeten Typen recht interessant...



  • Na dann liste ich doch mal ein paar konkrete Beispiele auf (aus einem Unicode Projekt):

    RegQueryValueEx() will z.B. einen Buffer vom typ LPBYTE um das Ergebnis zu speichern. Habe ich bisher mit CString und (BYTE 😉 installDir.GetBufferSetLength( (int)dwSize ) gemacht, wobei dwSize ein DWORD ist.

    Das ganze liefert mir in meinem Fall eine Pfadangabe, die passe ich mit CString.Append() an.

    ShellExecute() will dann als Parameter einen LPCWSTR. Also benutze ich im Moment lstrcpyW(path, installDir) um es zufrieden zustellen.

    An anderer Stelle hole ich mir mit getenv() den Wert von %windir%, was mir einen char * liefert. Wird als Parameter dem Konstruktor eines CStrings übergeben damit dieser dann mit Append() und AppendFormat() angepasst werden kann. Hier benutze ich dann erstmal CFile::GetStatus(), was einen LPCTSTR erwartet. Dann kommen einige Dateioperationen mit fgets, fwrite (jeweils char) wobei ich zwischen durch den String durchsuchen muss, wozu ich im Moment erst nach CString konvertiere und dann wieder zurück.

    Zwischendrin füttere ich dann noch einige MessageBox() Aufrufe mit zuvor angepassten strings ála LPCWSTR str = A2BSTR("Erfolg") bzw. bekomme für einige Funktionsaufrufe mit festen Strings einige wchar_t dazu.

    Wie man sieht ein heilloses Durcheinander, das zwar kompiliert und auch funktioniert, aber mir alles andere als sinnvoll und schon gar nicht elegant erscheint.


Log in to reply