AnsiString = AnsiString funktioniert nicht!?
-
Hai Leute!
Hab folgendes Problem und zwar habe ich einen AnsiString namens Symbol1 in dem steht (debuggt) z.B. "images\\white.bmp"
Nun hab ich einen 2. AnsiString:
AnsiString Old; [...] Old = Symbol1;Und hier eben das Problem, "Old" wird kein Wert zugewiesen
, laut Debugger ist der auch nachher noch NULL.
Ich meine, mir ist schon klar, dass das z.B. geht:AnsiString lala = Edit1->Text;Aber was mach ich denn schon wieder falsch, im Prinzip ist es ja gar kein Unterschied, und in Symbol1 steht 100%ig etwas drin
Hab auch sonst im Forum nichts Passendes gefunden, bitte helft mir bei meinem blöden Problem!
-
Sollte 'AnsiString Old' nicht global sein, zeigt es nur, daß bei 'Old = Symbol1;' AnsiString 'Symbol1' NULL ist.
Hier ist kein Fehler zu sehen, also muß es wo anders an deinem Code liegen
-
OldMan00 schrieb:
Sollte 'AnsiString Old' nicht global sein, zeigt es nur, daß bei 'Old = Symbol1;' AnsiString 'Symbol1' NULL ist.
Hier ist kein Fehler zu sehen, also muß es wo anders an deinem Code liegenApropo global: Symbol1 ist ein globaler AnsiString (ja ich weiß, globale Variablen sind "böse"...) aber wenn ich mit dem Debugger vorher auf 'Symbol1' gehe, zeigt er mir den Wert an, den ich auch reingeschrieben habe (also das macht er richtig), nun hab ich nichts anderes getan als praktisch den String kopiert, das müsste mir der Debugger aber schon anzeigen, oder (,wenn ich Dich richtig verstanden habe,) nicht?
Aber ansonsten gibt es fast keinen Code, und schon gar keinen der sonst auf 'Old' zugreift!Jetzt wirds aber spannend...
-
was ich meine ist, daß 'AnsiString Old;' so nicht NULL ist !
mach doch einfach folgendes:
scheibe direkt vor der Zuweisung 'Old = Symbol1;'ShowMessage("Old = " + Old + "\nSymbol1 = " + Symbol1); Old = Symbol1;dann siehst Du welche Werte die Variablen besitzen.
ShowMessage ist manchmal der beste Debugger den es gibt, gerade für soetwas.edit:
Du brauchst auch nur vor der Zuweisung einen Haltepunk zu setzten und mit der Maus über die Variablen zu gehen.
-
Hallo,
Welchen Builder verwendet ihr denn? Beim 2007er ist es häufig so, dass selbst im Debug-Modus Variablen rausoptimiert werden können. Da geht ihr dann am besten mal in die Options Punkt Optimierungen und schaltet dort alle verbliebenen Optimierungen ab.
-
ich gehe mal davon aus, daß er den 6er meint, da er ja zu diesem Zeitpunkt geschrieben hatte, die 7er funktioniert bei ihm nicht und der 6er gefällt ihm bei weiten besser.
-
Sorry, konnte nicht früher schreiben (Schule)
OldMan00 schrieb:
ich gehe mal davon aus, daß er den 6er meint, da er ja zu diesem Zeitpunkt geschrieben hatte, die 7er funktioniert bei ihm nicht und der 6er gefällt ihm bei weiten besser.
Ja genau, benutze BCB 6, habe nun auch mit ShowMessage(Old); den String ausgegeben, das Fenster zeigt aber nichts an (also wie im Debugger angezeigt).
Vielleicht mach ich ja einen Denkfehler
Hier nochmal das Wichtigste meines Programms:
const.h:
AnsiString Symbol1; //gloable DeklarationKonstrukter der Form1:
Symbol1 = "images\\circle.bmp"; //(relativer) Pfad des Bitmaps, welches standardmäßig geladen wirdOnClick-Ereignis eines Images in der TChangeSymbol-Form:
void __fastcall TChangeSymbol::Image4Click(TObject *Sender) { AnsiString Old; if(RadioButtonP1->Checked) { //change symbol of player1 Old = Symbol1; //change the old symbols to the new one: change_symbols(Old,Symbol1); } //[...] }Nun der eigentliche Sinn ist es, dass der User das Bild, welches er als Logo haben will, auswählen kann. Im aktuellen Spiel sollte man das alte Spielfeld dann durch die neuen Symbole ersetzen, dadurch muss jedoch auch das alte Symbol bekannt sein (da nicht alles die gleichen Felder sind). Ja das wär's, ich weiß es gäbe auch andere Methoden, aber das hier ist wohl die einfachste, indem ich später die AnsiStrings Old und die gespeicherten im Spielfeld überprüfe und falls notwendig ersetze
Ja es funktioniert leider nicht, ansonsten wird Old aber auch nirgends verändert!?
Hilfe, Abgabetermin ist in einer Woche!
-
Hast Du in der Deklaration von TChangeSymbol noch ein zweites Symbol1?
-
witte_ schrieb:
Hast Du in der Deklaration von TChangeSymbol noch ein zweites Symbol1?
Nein auch nicht. Hab auch schon Symbol1 umbenannt (und natürlich überall wo es vorkam), zeigt aber immer noch denselben Fehler!
-
void __fastcall TChangeSymbol::Image4Click(TObject *Sender) { AnsiString Old; if(RadioButtonP1->Checked) { //change symbol of player1 ShowMessage(Symbol1); Old = Symbol1; ShowMessage(Old); //change the old symbols to the new one: change_symbols(Old,Symbol1); } //[...] }Was gibt dir dieser Quelltext in der ersten bzw. zweiten Box aus?
-
OK, habs jetzt endlich fertig!
Ich weiß nicht genau an was es lag, hab mehrere Änderungen durchgenommen:
- Include-Guards (bei den Konstanten) hinzugefügt
- aus konstanten AnsiStrings variable gemacht (werden natürlich nicht verändert)
das hat nämlich immer zu Linker-Errors geführt
(Einbindung der Variablen in der Header mittels externNochmal durch Debuggt und plötzlich ging die Zuweisung

Wahrscheinlich lag es an den nicht vorhandenen Include-Guards (achtet immer auf die Linker-Warnungen)Auf jedenfall funktioniert es nun

-
Das ist halt das Problem mit globalen Variablen. Da tauche derartige Dreckeffekte immer mal wieder auf. Eigentlich ist das ein deutliches zeichen dafür sein Design zu überdenken.

-
Braunstein schrieb:
Das ist halt das Problem mit globalen Variablen. Da tauche derartige Dreckeffekte immer mal wieder auf. Eigentlich ist das ein deutliches zeichen dafür sein Design zu überdenken.

Ja aber gehört es auch zum guten Programmierstil seine Konstanten nicht global zu definieren? Ich meine hier sind nicht alles Konstanten okay versteh ich, im nächsten Projekt werde ich das anders machen. Aber wenn die Konstanten von (fast) allen Forms gebraucht werden, sollte man dann auch nicht global deklarieren?
-
Bei Konstanten kann man das schon so machen. Ich bevorzuge hier aber eher eine struct in der alle diese Konstanten zusammengefasst werden. Die lege ich dann in einen Singleton ab.
Bei performancekritischen Programmteilen arbeite ich aber auch mit extern.
Ich hatte hier irgendwie nicht gesehen, dass es sich um globale Konstanten handeln soll (kein const).
-
Braunstein schrieb:
Bei Konstanten kann man das schon so machen. Ich bevorzuge hier aber eher eine struct in der alle diese Konstanten zusammengefasst werden. Die lege ich dann in einen Singleton ab.
Bei performancekritischen Programmteilen arbeite ich aber auch mit extern.
Ich hatte hier irgendwie nicht gesehen, dass es sich um globale Konstanten handeln soll (kein const).Es waren auch nicht alle global (z.B. Symbol, Symbol2), aber z.B. triangle,cross,... waren globale AnsiStrings. Diese habe ich früher auch als konstant (const) deklariert, durch das extern wollte mir der Linker das aber nie abnehmen (auch wenn ich extern const AnsiString... schrieb). Er brachte immer eine Linker-Error z.B. Undefined Symbol _triangle (mit Unterstrich). Ich habe nun zu Testzwecken das const entfernt und da nur ich an diesem Projekt arbeite, auch darauf geachtet sei nirgends zu verändern (ich weiß, kein guter Programmierstil, aber wenn der Linker nicht mitspielt)
-
extern const AnsiString ist kein Problem. Wenn dein Linker da nicht mitspielt hast du was anderes falschgemacht.
-
Braunstein schrieb:
extern const AnsiString ist kein Problem. Wenn dein Linker da nicht mitspielt hast du was anderes falschgemacht.
Ja aber wenn ich sie nicht konstant deklariere funktioniert alles, wenn ich alles auf const umändere:
const.h:const AnsiString triangle = "images\\triangle.bmp";Unit2.cpp:
extern const AnsiString triangle;Das führt zu folgendem Linkererror:
[Linker Fehler] Unresolved external '_triangle' referenced from K:\TICITACTOE\TICITACI6\UNIT2.OBJda ist wohl ansonsten nichts falsch, oder schon? Ach ja, const.h wird in Unit1.h inkludiert, ebenso Unit2.h
-
Du machst es ja auch genau verkehrt rum. Das
extern const AnsiString triangle;gehört in den Header und die Definition in eine cpp.
-
Braunstein schrieb:
Du machst es ja auch genau verkehrt rum. Das
extern const AnsiString triangle;gehört in den Header und die Definition in eine cpp.
Ja aber ich definiere die AnsiStrings in meinem Header const.h, wo sie ihren (konstanten) "Wert" zugewiesen bekommen. Somit ist das praktisch einfach eine normale Header-Datei.
Aus der Unit1 rufe ich dann die Unit2 auf, in welcher ich nun mittels extern diese AnsiStrings "einbinde". Wenn ich die extern-Deklaration in den Header der Unit2 schiebe, bleibt es bei den selben Linker Errors.
-
Hallo
Braunstein hat schon recht. Probier es doch einfach mal aus.
bis bald
akari
-
Erläuterungen zu extern und globale Variablen.
http://www2.informatik.uni-halle.de/lehre/c/c_globv.html
http://www.willemer.de/informatik/cpp/geltungvar.htm