Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

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

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.

die GetAt() - Methode hat wunderbar funktioniert....besten Dank an alle!

VincentVega

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.

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.

"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?

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.

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.

So gehts:

CString EinString;

const char *chars = EinString.c_str();

char wert = chars[0];

stimmt ...

mit CString gehts so:

CString mystring

char mychar = mystring[0];

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.