Römische Zahlen
-
chris090980 schrieb:
Hat jemand von euch das Programm schonmal ausprobiert ?
Ja, aber es war nervig, weil ich erstmal mit Fehleren überhäuft wurde.
Der überladene >>-Operator scheint alles richtig zu machen. Die eingelesenen Daten kommen richtig an, das hab ich schon mit der Überwachung geprüft.
Wa? Welche Überwachung?
Später gehen sie jedoch verloren.
Wie lang ist später?? Wann is später?
Hängt das mit der Sichtbrakeit zusammen?
Nein, nicht hauptsächlich.
Und wenn ja, wie löse ich das dann?
Du löst es am besten indem du vorher noch etwas übst mit einfacheren Beispielen.
Kann mir jemand weiterhelfen?
Klar. Schau dir mal deinen Operator an:
istream& operator >> (istream& is, roemisch obj) { if (i == 0) is >> obj.arab; else is >> obj.rz; i=1; return is; }Was ist i? Wofür ist das gut?? Erster Tipp: Den Variablen bessere Namen geben und KEINE globalen Variablen.
Wofür ist die if-Abfrage gut? Zweiter Tipp: Kommentieren.
Weißt du was das & nach dem istream bedeutet oder hast du das nur abgeschrieben? Wenn ja, dann informiere dich darüber, was es bedeutet. Wenn du es schon weißt, solltest du wissen wo der Wert verloren geht. (Kleiner Tipp: Am Ende von der Operator-Funktion)mfg.
-
Tja, jetzt bin ich genauso schlau wie vorher!
ich will r1 und r2 ja addiren und da läuft was schief, weil
am ende nichts raus kommt. und ich weiß nicht warum die werte
plötzlich verschwinden, nachdem ich sie zuweise.Was ist i? Wofür ist das gut??
Das ist doch jetzt erstmal egal.
Wofür ist die if-Abfrage gut?
Das spielt auch keine Rolle.
Weißt du was das & nach dem istream bedeutet oder hast du das nur abgeschrieben?
Nein, aber das hättest dz mir doch sagen können.
(Kleiner Tipp: Am Ende von der Operator-Funktion)
Kann nicht sein, beim operator<< mach ich ja im Prinzip dasselbe und da geht auch nichts verloren.
Wenn jemand Lust hat zu antworten, dann bitte ausführlich. "Kleiner Tipp" bringt mich nicht weiter. Bin halt kein SuperProfi wie ihr !!!
mfg.
-
chris090980 schrieb:
Tja, jetzt bin ich genauso schlau wie vorher!
ich will r1 und r2 ja addiren und da läuft was schief, weil
am ende nichts raus kommt. und ich weiß nicht warum die werte
plötzlich verschwinden, nachdem ich sie zuweise.Schon nach dem >>-Operator ist nichts gespeichert. Schau:
int main() { roemisch r1; cin >> r1; cout << r1; }Ausgabe:
IV -1Was ist i? Wofür ist das gut??
Das ist doch jetzt erstmal egal.
Es kommt aber in dem Code vor, und wir sollen dir doch helfen oder? Dann musst du es auch erklären.
Weißt du was das & nach dem istream bedeutet oder hast du das nur abgeschrieben?
Nein, aber das hättest dz mir doch sagen können.
Dafür gibt es Tutorials und Bücher, und ich habe keine Lust jedem das zu erklären, das können andere besser. Googel ein bisschen. Beispiel: http://web.dadanini.com:7980/books/C++ in 21 Tagen/kap09.html
mfg.
-
Wenn man Hilfe will, sollte man den Leuten von denen man Hilfe möchte auch ein Programm geben was ohne Probleme läuft und bei Fehlern diese zu Herzen nehmen und schonmal mit der Korrektur anfangen. Und wenn man dir Fragen stellt, werden diese schon einen Sinn ergeben und dann kann man als Helfer auch erwarten das du diese beantwortest.
Ich würde sagen beim Eingabeoperator muss der Parameter mit dem einzulesenden Objekt als Referenz übergeben werden.
Nur weil etwas bei einem Operator funktioniert, funktioniert dies nicht auch bei einem anderen.
-
Kommentier doch bitte mal die "cin-Anweisungen" aus und füge folgendes bei main()
ein:r1 = 22; r2 = "IV";Ausgabe: 26 //Integer Zahl (22+4)
das klappt echt wunderherrlich. da geht nichts verloren.
Im Internet steht das das Objekt nach Ende der Funktion nicht mehr existiert wenn ich da ein "&" hinschreibe, weil es dann eine referenz ist. Es wird empfohlen das "&-Zeichen" einfach wegzulassen. Super, aber das funktioniert dann nicht mehr.
Dann gab es noch den Tipp, eine "friend-Funktion" draus zu machen. Das führt aber auch zu einem Fehler.P.S.: Ich bitte euch, das "i" hat echt nichts mit meinem Problem zu tun. Das ist eine globale Variable, und dient dazu das ich sicherstelle das zuerst eine arabische Zahl eingelesen wird und danach eine römische.
Ja ich weiß das das unsauber ist, aber das interessiert den Professor nicht dem ich das zeigen soll(der ist da sehr tollerant), der will nur das es läuft.
Ich hab jetzt alles ausprobiert mit "*" und mit "&" und eine "freind-Funktion" und nichts geht. Zur Not wüsste ich wie ich das mache, aber das wird dann noch unsauberer und noch schlechter will ich das eigentlich nicht machen.
-
chris090980 schrieb:
Kommentier doch bitte mal die "cin-Anweisungen" aus und füge folgendes bei main()
ein:r1 = 22; r2 = "IV";Ausgabe: 26 //Integer Zahl (22+4)
das klappt echt wunderherrlich. da geht nichts verloren.
Ich sage dir: Bei dem >>-operator ist der Fehler und du sagst mir wenn man ihn auskommentiert geht's. Also wirklich, das was du mir da gezeigt hast, ist kein Beweis dafür, dass es nicht am >>-operator liegt.Im Internet steht das das Objekt nach Ende der Funktion nicht mehr existiert wenn ich da ein "&" hinschreibe, weil es dann eine referenz ist.
Ich bin auch gerade im Internet, aber da steht das gar nicht.

Es wird empfohlen das "&-Zeichen" einfach wegzulassen. Super, aber das funktioniert dann nicht mehr.
Wenn du das &-Zeichen weglässt funktioniert das weglassen von dem &-Zeichen nicht mehr??!? Hä?
P.S.: Ich bitte euch, das "i" hat echt nichts mit meinem Problem zu tun. Das ist eine globale Variable, und dient dazu das ich sicherstelle das zuerst eine arabische Zahl eingelesen wird und danach eine römische.
Das müssten wir doch auchmal wissen oder??? Sonst geben wir als erstes eine römische ein und wundern uns warum es nicht klappt.
Das Problem ist folgendes:
#include <iostream> using namespace std; struct Widget { int value; }; void Foo(Widget w) { w.value = 456; } void Bar(Widget& w) { w.value = 789; } int main() { Widget w; w.value = 123; cout << w.value << endl; // Sollte 123 sein, klappt Foo(w); cout << w.value << endl; // Sollte 456 sein, klappt nicht Bar(w); cout << w.value << endl; // Sollte 789 sein, klappt }Bei der Foo-Funktion wird ein neues Widget-Objekt erstellt, welches nur solange existiert wie Foo() ausgeführt wird. Dieses neue Objekt ist eine Kopie des alten, aber an dem alten wird nichts geändert. Beim zweiten geht's und es sollte klar sein warum.
mfg.
-
Ich habe jetzt einen Teilerfolg erzielt. er behält jetzt den wert von r1. der wert von r2 (römischer Teil) geht aber immer nochverloren und somit null. deswegen ist r1+r2=r1
meine überladene Funktion sieht nun so aus:
roemisch &operator >> (istream& is, roemisch &obj) { if (i == 0) is >> obj.arab; else is >> obj.rz; i=1; return obj; }Frage: Wie muss die Funktion aussehen damit auch der römische Teil erhalten bleibt.
Und: Geht das überhaupt so wie ich mir das vorstelle (r1+r2)?
Hinweis: Das ergebnis darf arabisch oder auch römisch sein.
Schön wäre es jedoch wenn sich durch eine kline Modifikation der typ des ergebnisses ändern lassen würde( z.b. von arabisch nach römisch).Im Internet steht noch (Zitat):
Enthält das zu zurückzugebende Objekt dynamische Daten (Zeiger!), so muss die Klasse des Objekts in der Regel den Kopierkonstruktor und einen überladenen Zuweisungsoperator besitzen! Mehr dazu nachher gleich.
muss ich das auch machen? Glaub ich eigentlich nicht.
Quelle: http://www.cpp-tutor.de/cpp/le09/le09_01.htm#oreturn
-
Eigentlich war dein Operator vorher schon ganz richtig, außer das roemisch keine Referenz war. Du musst istream zurückgeben (wie zuvor) und nicht roemisch. Ansonsten sind solche Ketten hier nicht möglich:
cin >> obj1 >> obj2;
-
Ich wollte nur sagen das ich jetzt weiß woran es liegt. Ich muss zur Behebung einen string in einen "array of character" umwandeln. das müsste doch mit:
string s="XXX"; s.data();gehen, oder? Ich versuch das mal.
geht das auch noch anders ? Wenn ja, wie denn?
-
.c_str()
-
Zur Information: In r1 und r2 werden jetzt die Werte dauerhaft gespeichert. Gehen also nicht mehr verloren. Sie kommen auch in der Funktion an, in der ich sie haben will.
Ich steh jetzt kurz vor dem Durchbruch und jetzt bekomme ich so 'ne blöse string umwandlung nicht hin. Ich weiß das ist eigentlich total billig, aber ich krieg das nich hin. Das beispiel in der Hilfe sieht schon ganz gut aus, aber ich will den array of character an eine funktion übergeben und das will der compiler nicht.
roemisch roemisch::operator+(roemisch obj) { roemisch hilf; int temp; const char *ptr1 = 0; if (arab != 0) { hilf.arab = arab + obj.rom2dec(ptr1); } else { temp = this->rom2dec(this->rom_zahl); temp += obj.arab; cout<<"\nobj.arab ist: "<<obj.arab; cout<<"\ntemp ist: "<<temp; hilf.rz = hilf.dec2rom(temp); cout<<"\nhilf.rz ist: "<<hilf.rz; } return hilf; }da kommt die Fehlermeldung: error C2664: 'roemisch::rom2dec': Konvertierung des Parameters 1 von 'const char *' in 'char []' nicht möglich
Hinweis: der parameter der funktion lautet: char rom[]
Kann mir bitte jemand sagen wie ich das machen muss?
Das ist echt das einzigste was ich noch brauche (hoffe ich).
-
"const Typ" kann nicht nach "Typ" konvertiert werden. Du müsstest deinen Parameter also zu const char* machen, statt char*. Allerdings kannst du dann nur lesend auf das Array zugreifen. Wenn du das nicht willst, solltest du als Parameter string verwenden.
-
Ok, ich habe es jetzt geschafft. Das Lösung ist jetzt zufriedenstellend. Nochmal Danke an alle die mir geholfen haben.
Für den Fall das ihr wissen wollt wie ich das gemacht habe, hab ich hier nochmal den kompletten Code eingefügt.
#include "stdafx.h" #include <conio.h> #include <string> #using <mscorlib.dll> using namespace System; using namespace std; int i=0; class roemisch { public: roemisch operator+(roemisch obj); roemisch operator=(int i); roemisch operator=(char c[]); roemisch(void) { } //roemisch(char s[20]) roemisch (string g) { rz = g; /*for(int k=0; k<20; k++) { rom_zahl[k] = s[k]; }*/ cout<<rz; } roemisch(int i) { cout<<"i ist:"<<i; arab = i; } string dec2rom(int dec) { int i,j; char str[20]; short laenge; string erg; itoa(dec, str, 10); laenge = strlen(str); j=0; i = 4-laenge; //Ins richtige Segment springen je nachdem ob die zahl 4,3,2 oder 1-stellig ist. for (i; j<laenge; i++) //Tausender, Hunderter, Zehner und EinerStellen prüfen { if(i==0) //Tausender Stelle { if (str[j] == '0') {erg+="";} if (str[j] == '1') {erg+="M";} if (str[j] == '2') {erg+="MM";} if (str[j] == '3') {erg+="MMM";} j++; } if(i==1) //Hunderter Stelle { if (str[j] == '0') {erg+="";} if (str[j] == '1') {erg+="C";} if (str[j] == '2') {erg+="CC";} if (str[j] == '3') {erg+="CCC";} if (str[j] == '4') {erg+="CD";} if (str[j] == '5') {erg+="D";} if (str[j] == '6') {erg+="DC";} if (str[j] == '7') {erg+="DCC";} if (str[j] == '8') {erg+="DCCC";} if (str[j] == '9') {erg+="CM";} j++; } if(i==2) //Zehner Stelle { if (str[j] == '0') {erg+="";} if (str[j] == '1') {erg+="X";} if (str[j] == '2') {erg+="XX";} if (str[j] == '3') {erg+="XXX";} if (str[j] == '4') {erg+="XL";} if (str[j] == '5') {erg+="L";} if (str[j] == '6') {erg+="LX";} if (str[j] == '7') {erg+="LXX";} if (str[j] == '8') {erg+="LXXX";} if (str[j] == '9') {erg+="XC";} j++; } if(i==3) //Einer-Stelle { if (str[j] == '0') { erg+="";} if (str[j] == '1') {erg+="I";} if (str[j] == '2') {erg+="II";} if (str[j] == '3') {erg+="III";} if (str[j] == '4') {erg+="IV";} if (str[j] == '5') {erg+="V";} if (str[j] == '6') {erg+="VI";} if (str[j] == '7') {erg+="VII";} if (str[j] == '8') {erg+="VIII";} if (str[j] == '9') {erg+="IX";} j++; } } //Ende for-Schleife für i cout<<"\nerg ist: "<<erg; return erg; } int rom2dec(string rom) { int laenge; int summe=0; laenge = rom.length(); for (int i=0; i<laenge; i++) { //Ist das erste Zeichen 'I' oder 'X'&& Ist es nicht die ZK "XI"? && Um z.b. XX zu stoppen für einzelzeichen wenn man z.b. nur 'X' eingibt if (((rom[i]=='I')||(rom[i]=='X')) && ((rom[i]!='X') || (rom[i+1]!='I')) && ((rom[i]!=rom[i+1]) && (rom[i+1]!='\0'))) { //Sonder-Liste if ((rom[i] == 'I') && (rom[i+1] == 'V')) summe+=4; if ((rom[i] == 'I') && (rom[i+1] == 'X')) summe+=9; if ((rom[i] == 'I') && (rom[i+1] == 'C')) summe+=99; if ((rom[i] == 'I') && (rom[i+1] == 'M')) summe+=999; if ((rom[i] == 'I') && (rom[i+1] == 'D')) summe+=499; if ((rom[i] == 'I') && (rom[i+1] == 'L')) summe+=49; if ((rom[i] == 'X') && (rom[i+1] == 'C')) summe+=90; if ((rom[i] == 'X') && (rom[i+1] == 'M')) summe+=990; if ((rom[i] == 'X') && (rom[i+1] == 'L')) summe+=40; if ((rom[i] == 'X') && (rom[i+1] == 'D')) summe+=490; break; //Keine weiteren Zeichen erlaubt. } else //Standard-Liste { if (rom[i] == 'M') summe+=1000; if (rom[i] == 'C') summe+=100; if (rom[i] == 'X') summe+=10; if (rom[i] == 'I') summe+=1; if (rom[i] == 'D') summe+=500; if (rom[i] == 'L') summe+=50; if (rom[i] == 'V') summe+=5; } } return summe; } string rz; int r, arab; char rom_zahl[20]; }; roemisch roemisch::operator+(roemisch obj) { roemisch hilf; int temp; const char *ptr1 = 0; if (arab != 0) { hilf.arab = arab + obj.rom2dec(obj.rz); } else { temp = this->rom2dec(this->rz); temp += obj.arab; cout<<"\nobj.arab ist: "<<obj.arab; cout<<"\ntemp ist: "<<temp; hilf.rz = hilf.dec2rom(temp); cout<<"\nhilf.rz ist: "<<hilf.rz; } return hilf; } roemisch roemisch::operator=(int i) { roemisch hilf; this->arab=i; return *this; } roemisch roemisch::operator=(char c[]) { this->rz = c; return *this; } ostream& operator<<(ostream& os, roemisch obj) { if (obj.arab != 0) os <<obj.arab; else os <<obj.rz; return os; } roemisch &operator >> (istream& is, roemisch &obj) { if (i == 0) is >> obj.arab; else is >> obj.rz; i=1; return obj; } void main() { roemisch r1; roemisch r2; roemisch r3; cout<<"\nr1(arabisch): "; cin>>r1; cout<<"r2(roemisch): "; cin>>r2; //r1 = 50; //r2 = "XX"; cout<<"r2.rz ist: "<<r2.rz; cout<<"r2.romzahl ist: "<<r2.rom_zahl; cout<< "\nneu: "<<r1+r2; getch(); }