VincentVega Geschrieben 3. Dezember 2002 Geschrieben 3. Dezember 2002 hallo erstmal. sitz hier gerade an nem programm bei dem ich einen wert aus ner mfc-anwendung als cstring erfasse. is nur ein zeichen, kann aber nichts daran ändern dass der als cstring erfasst wird. im weiteren muss ich jetzt aber mit diesem wert als "char" weiterarbeiten. der compiler meckert dann natürlich , dass konvertierung von "char *" in"char" nicht so einfach geht. hab allerdings gerade auch keine ahnung wie ich das problem lösen könnt, wenn also einer von euch nen tip hätt, wär ich sehr dankbar. mfg mike PS: ich weiß dass das nen anfängerproblem is, aber ich weiss im moment echt nicht weiter Zitieren
Klotzkopp Geschrieben 3. Dezember 2002 Geschrieben 3. Dezember 2002 char c = DeinCString[0]; Zitieren
Crush Geschrieben 3. Dezember 2002 Geschrieben 3. Dezember 2002 Mach ´ne Referenz drauf: CString Test("x"); char&v=(char&)*(LPCSTR)Test; aber Vorsicht: Die Lebensdauer vom CString muß gleich oder länger sein als der char! oben wird eine Kopie angelegt und bei mir tatsächlich der CString selbst anvisiert. Es gibt bei CString noch die Methode GetAt() fürs Abfragen. Beim nächsten Mal vielleicht dazuschreiben, was Du genau gemacht hast. Zitieren
Klotzkopp Geschrieben 3. Dezember 2002 Geschrieben 3. Dezember 2002 Originally posted by Crush CString Test("x"); char&v=(char&)*(LPCSTR)Test; [/CODE][/b]Du erzeugst eine nicht-const-Referenz auf einen const char? Da krieg ich eine Gänsehaut... Zitieren
VincentVega Geschrieben 3. Dezember 2002 Autor Geschrieben 3. Dezember 2002 die GetAt() - Methode hat wunderbar funktioniert....besten Dank an alle! VincentVega Zitieren
Crush Geschrieben 3. Dezember 2002 Geschrieben 3. Dezember 2002 char c = DeinCString[0]; erlaubt es ja auch c neu zu definieren! Kommt ja auf den gewünschten Einsatz an. Aber wenn man´s genau nimmt, darf man auch nicht einfach eine konstante Referenz auf einen unbeständigen CString machen, also kann man das noch breiter treten: CString Test('x'), Neuerstring("Pech!"); // wenn man unbedingt alles abgesichert haben möchte... Test.OemToAnsi(); Test.Truncate(1); Test.GetBufferSetLength(1); Test.LockBuffer(); const char& v = (const char&) *(LPCSTR)Test; Test = Neuerstring; // hier mal auf v schauen! Das bringt so nichts. CString n = Neuerstring; // hoppla, was ist denn mit den Adressen von n und Neuerstring? // die sind jetzt nämlich gleich, weil sie auf den selben String zeigen!!! char& w = (char&) *(LPCSTR)Neuerstring; // LPSTR will er ja nicht so einfach! w='?'; // jetzt sind Neuerstring und n gleich (ist ja die gleiche Adresse) Neuerstring.SetAt(0,'?'); // verändert man indirekt etwas an einem String erhält er eine neue Adresse // denn: es wird ein komplett neuer String angelegt Wie man sieht bringt es gar nichts, eine Referenz auf einen CString konstant zu deklarieren, wenn nicht der CString selbst konstant ist, weil die CString-Objekte über Zeiger bei Änderungen umgebogen werden! Natürlich würde ich auch das Herauskopieren des Charakters vorziehen! Aber nach der Fragestellung hätte man das ganze auch so verstehen können, daß der CString und der char ein und dasselbe Zeichen sein sollen! Über den Buffer "GetBuffer()" oder "GetBufferSetLength()" darf man ja auch nicht gehen, weil der üblicherweise auch nur temporär ist. Zitieren
Klotzkopp Geschrieben 3. Dezember 2002 Geschrieben 3. Dezember 2002 Originally posted by Crush char c = DeinCString[0]; erlaubt es ja auch c neu zu definieren! Kommt ja auf den gewünschten Einsatz an. Ja. Aber ich arbeite dann mit einer "legalen" Kopie. char& w = (char&) *(LPCSTR)Neuerstring;Das ist doch nach wie vor dasselbe Problem. Du castest das const raus, und hast damit undefiniertes Verhalten. Dass das bei CString und Deinem Compiler funktioniert, ist reines Glück. Ein Beispiel:LPCSTR p = "x"; char& w = (char&)(*p); w = 'y';[/CODE]Was macht das bei Dir? [b]Aber nach der Fragestellung hätte man das ganze auch so verstehen können, daß der CString und der char ein und dasselbe Zeichen sein sollen! [/b]Diese Art von Synchronisierung kann aber nicht legal funktionieren, weil CString keine nicht-const-Referenzen rausgibt, sondern nur Kopien oder const-Zeiger. Jeder schreibende Zugriff auf den CString kann den Zeiger, den der LPCSTR-Operator zurückgegeben hat, ungültig machen, und dann hast Du eine ungültige Referenz. Zitieren
Crush Geschrieben 3. Dezember 2002 Geschrieben 3. Dezember 2002 "Was macht das bei Dir?" Er knallt natürlich eine Exception raus! "Diese Art von Synchronisierung kann aber nicht legal funktionieren, weil CString keine nicht-const-Referenzen rausgibt, sondern nur Kopien oder const-Zeiger. Jeder schreibende Zugriff auf den CString kann den Zeiger, den der LPCSTR-Operator zurückgegeben hat, ungültig machen, und dann hast Du eine ungültige Referenz." Klar, deshalb kann das nur dann ordentlich funktionieren, wenn man sich gleich an Ort und Stelle alles aus dem CString rauskopiert (wenn man unbedingt auf diese harte Tour rangeht) und sofort wieder die Finger davon läßt. Deshalb sollen ja Funktionen nur Werte kopieren, per Referenz als Argument übergebene Daten ausfüllen, sich selbst oder neu angelegte Objekte übergeben. Alles andere ist verboten. Auf die Members (oft selber per Referenzen beinhaltet) sollte man eigentlich gar nicht von außen direkt zugreifen, auch wenn man wie bei CString eben direkt an die Adressen rankommen kann - das sollte nur Friends erlaubt sein, die genau "wissen" was sie tun. Deshalb sage ich ja: Nur konstante Zeiger auf konstante Objekte. Wie mein Beispiel allerdings gezeigt hat, ist auch der LPCSTR auch keine Garantie ob die Referenz stimmt. Darum ist ja auch das Kopieren des chars wie Du es tust hier die einzig richtige Lösung (obwohl der []-Operator dafür wohl auch nicht unbedingt die richtige Zugriffsmethode ist. Angenommen der String wäre leer? Zitieren
Klotzkopp Geschrieben 3. Dezember 2002 Geschrieben 3. Dezember 2002 Originally posted by Crush obwohl der []-Operator dafür wohl auch nicht unbedingt die richtige Zugriffsmethode ist. Angenommen der String wäre leer? CString::GetAt und CString::operator[] sind identisch. Sie machen nur Assertions auf ungültige Indices, also hast Du Recht: Man sollte vorher die Länge prüfen. Zitieren
Crush Geschrieben 3. Dezember 2002 Geschrieben 3. Dezember 2002 Bei der STL sind allerdings der []-Operator und GetAt() unterschiedlich. Letztes nimmt nämlich eine Bereichsprüfung vor - Ersteres nicht. Man kann sich wohl auf Namensgleichheiten von Funktionen eben auch nicht immer verlassen. Zitieren
M.A.Knapp Geschrieben 4. Dezember 2002 Geschrieben 4. Dezember 2002 So gehts: CString EinString; const char *chars = EinString.c_str(); char wert = chars[0]; Zitieren
Klotzkopp Geschrieben 5. Dezember 2002 Geschrieben 5. Dezember 2002 Originally posted by M.A.Knapp EinString.c_str();Das gibt es bei std::string und AnsiString, aber nicht bei CString. CString hat einen cast-Operator für const TCHAR*. Zitieren
M.A.Knapp Geschrieben 5. Dezember 2002 Geschrieben 5. Dezember 2002 stimmt ... mit CString gehts so: CString mystring char mychar = mystring[0]; Zitieren
Guybrush Threepwood Geschrieben 5. Dezember 2002 Geschrieben 5. Dezember 2002 mit CString gehts so: Schau mal was Klotzkopp ganz oben geschreiben hat;) Gruß Guybrush Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.