Römische Zahlen
-
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(); }