Referenz wird neue Adresse nicht zugewiesen?
-
Hi, zunächst einmal soll der folgende Code nur das Problem reproduzieren und macht so sicherlich keinen Sinn.
Zum Problem. Ich möchte eine Zeichenfolge in Großbuchstaben wandeln, allerdings soll dazu nicht die originale Zeichenfolge verändert werden. Wird also ein kleiner Buchstabe gefunden so wird die ursprüngliche Zeichenfolge kopiert und die neue zurückgegeben.
Allerdings ist in der neuen Zeichenfolge immer der erste gefundene kleine Buchstabe nach wie vor klein und mir ist ein Rätsel warum:
bool needsCopy = true; char* original = new char[13]; original[0] = _T('H'); original[1] = _T('e'); original[2] = _T('l'); original[3] = _T('l'); original[4] = _T('o'); original[5] = _T(' '); original[6] = _T('W'); original[7] = _T('o'); original[8] = _T('r'); original[9] = _T('l'); original[10] = _T('d'); original[11] = _T('!'); original[12] = _T('\0'); char* copy = new char[13]; copy[0] = _T('H'); copy[1] = _T('e'); copy[2] = _T('l'); copy[3] = _T('l'); copy[4] = _T('o'); copy[5] = _T(' '); copy[6] = _T('W'); copy[7] = _T('o'); copy[8] = _T('r'); copy[9] = _T('l'); copy[10] = _T('d'); copy[11] = _T('!'); copy[12] = _T('\0'); char* result = original; for (int i = 0; i < 12; ++i) { char& c = result[i]; if ((c >= _T('a')) && (c <= _T('z'))) { if (needsCopy) { needsCopy = false; result = copy; c = result[i]; } c = c & 0x5F; } } printf(_T("Original: '%s'\n"), original); printf(_T("Result: '%s'\n"), result); delete[] original; delete[] copy;
Output:
Original: 'HEllo World!'
Result: 'HeLLO WORLD!'Es scheint als würde die Zeile
c = result[i];
einfach ignoriert. Folgender Code funktioniert dagegen, ist aber nicht sonderlich schön, da ich dann Code doppelt habe und eine weitere unnötige Referenz anlegen muss:
if ((c >= _T('a')) && (c <= _T('z'))) { if (needsCopy) { needsCopy = false; result = copy; char& c2 = result[i]; c2 = c2 & 0x5F; } else { c = c & 0x5F; } }
Output:
Original: 'Hello World!'
Result: 'HELLO WORLD!'Habe auch mal vor alle Variablen "volatile geklatscht" falls das ein Optimierungsfehler sein sollte, aber hat auch nichts genützt. Anyone?
-
Mir schwant was das Problem ist. Es wird gar nicht wie ich angenommen habe die Adresse der Referenz geändert sondern nur der Wert an die "alte" Adresse zugewiesen. Kann man denn überhaupt nachträglich die Adresse einer Referenz ändern?
-
Ok, geht anscheinend nicht. Werde wohl einen Pointer nehmen...
-
lernst du gerade absichtlich old school C++?
-
std::string ist die C++ Datenstruktur für Strings, nicht char Arrays.
_T ist eine Microsoft frickelei und passt mit der Verwendung von char nicht zusammen.
-
@DNKpp
Ja@manni
Ich würde eher sagen, dass der std::string eine von vielen Datenstrukturen für Strings (std::(w)string, CString, QString, mein eigener String, usw.) ist und nichtmal unbedingt die beste. Gefühlt hat mittlerweile jede Lib ihre eigene String Klasse.Naja UTF-16 als Gefrickel zu bezeichnen nur weil man unter z.B. Linux UTF-8 verwendet ist denke ich auch nicht fair. Und wenn unter Windows halt nunmal UTF-16 Standard ist verwende ich dieses auch.
Wie gesagt, das Beispiel war nur zum reproduzieren des Fehlers gedacht und für das Forum als Minimalbeispiel runtergebrochen. Aber ich wusste, dass ich irgendwas vergessen habe (_T) was jemand bemängeln wird. Hatte extra noch die deletes hingeschrieben, weil ich wusste dass sonst ein Kommentar kommt :). In Wirklichkeit verwende ich auch keinen "char".
Gebe dir aber recht, dass es unter Windows mit Strings echt eklig ist insbesondere wenn man noch 3rd Party Libs verwendet die dann UTF-8 Strings wollen.
-
Ich habe nicht behauptet, dass UTF-16 gefrickel ist.
-
*doppelt*
-
RefError schrieb:
@DNKpp
JaDann solltest du da nochmal dringen nach lernen, weil z.B. dein copy macht sicherlich nicht das, was du gerne hättest das es tut.
if (needsCopy) { needsCopy = false; result = copy; c = result[i]; }
Du kannst eine Referenz nur einmal initialisieren. Das was du mit c = result[i] machst ist eine einfache Zuweisung der darunter liegenden Variabel. Da ist logisch, dass das raus kommt, was du da gepostet hast. Also entweder nimmst du wirklich einen Pointer oder du arbeitest einfach mit dem Index i weiter.