C/C++ Römische in Arabische Zahlen konvertieren + Batchkonvertierung

Hallo!

Bin neu hier und komm auch gleich mit nem Problem daher.

Also ich mach seit gut 6 Wochen C und soll jetzt son Programm machen und komm einfach nicht damit zurecht. Wär schön wenn mir dabei einer ein wenig unter die Arme greifen könnte.

Also das Programm soll folgendermaßen aussehen.
1. Der User soll gefragt werden, ob er selber Zahlen eingeben möchte oder, ob er ne Batchkonvertierung machen möchte (batch mode ist mir im Moment nicht so wichtig, sollte aber im Endprogramm drin sein).
2. Das Programm soll Zahlen zwischen 1 und 4999 umwandeln können.
3. Das Programm soll die Subtraktionsregel befolgen
4. Größtmögliche röm. Zahl ist M = 1000

Zum Batchmode: Wenn Batchmode gewählt wird, soll das Programm nach dem Dateinamen der *.txt Datei fragen, in der sich die röm. Zahlen befinden und dann nach einem Dateinamen für die *.txt Datei in der sich die konvertierten Zahlen befinden.

Wie gesagt, ich hab grad erst mit C angefangen und komm damit nicht wirklich zurecht. Mir gehts im Moment erstmal darum, daß ich die Konvertierung von röm. in arab. Zahlen hinbekomme. Das mit dem batchen kann man hinterher immer noch angehen.

Ich hab mir mal folgenden Code von lagalopex ausm Programmieraufgaben Subforum genommen und editiert. Bekomm dann aber zwei Fehlermeldungen.

Original von legalopex:

Code:
#include <iostream>

using namespace std;

const int roemi[] = {5000, 4000, 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
const char roemc[][3]={"A", "MA", "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
const int arraynum = 15;
const int maxnum = 8888;

int main(int argc, char *argv[])
{
	int tmp;
	cout << "arabisch => roemisch" << endl;
	cout << "unter Anwendung der \"Subtraktionsregel\" (1..." << maxnum << ")" << endl;
	for(;;) {
		cout << "Zahl: " << flush;
		cin >> tmp;
		if(!tmp)
			break;
		if(tmp < 1 || tmp > maxnum)
			cout << "Ungueltige Zahl" << endl;
		else {
			cout << "roemisch: ";
			for(int i = 0 ; i < arraynum ; i++) {
				while(tmp >= roemi[i]) {
					tmp -= roemi[i];
					cout << roemc[i];
				}
			}
			cout << endl;
		}
	}
	return(0);
}

Mein abgeänderter Code:

Code:
#include <iostream>

using namespace std;

const char romc[] = ("M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I");
const int romi[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
const int arraynum = 13;
const int maxnum = 4999;

int main(int argc, char *argv[])
{
	int tmp;
	cout << "Roman to Arabic Number Converter" << endl;
	cout << "using the substraction rule" << endl;
	for(;;) {
		cout << "Please enter a Roman Number:" << flush;
		cin >> tmp;
		if(!tmp)
			break;
		if(tmp < 1 || tmp > maxnum)
			cout << "Illegal input!" << endl;
			cout << "Please enter a number that lies between 1 and 4999." << endl;
		else {
			cout << "Arabic Number:";
			for(int i = 0 ; i < arraynum ; i++) {
				while(tmp >= romc[i]) {
					tmp -= romc[i];
					cout << romi[i];
				}
			}
			cout << endl;
		}
	}
	return(0);
}

und die Fehlermeldung aus Visual C++ 2005:

Code:
------ Build started: Project: miniproject1, Configuration: Debug Win32 ------
Compiling...
mpr1.cpp
.\mpr1.cpp(5) : error C2440: 'initializing' : cannot convert from 'const char *' to 'const char []'
        There are no conversions to array types, although there are conversions to references or pointers to arrays
.\mpr1.cpp(23) : error C2181: illegal else without matching if
Build log was saved at "file://g:\My Projects\miniproject1\miniproject1\Debug\BuildLog.htm"
miniproject1 - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Aja, und wie mach ich hier Spoiler bzw. Hide Tags? funktioniert nicht :/
 
Code:
#include <iostream>
#include <string>

using namespace std;

const string romc[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
const int romi[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
const int arraynum = 13;
const int maxnum = 4999;

int main(int argc, char *argv[])
{
	int tmp;
	cout << "Roman to Arabic Number Converter" << endl;
	cout << "using the substraction rule" << endl;
	for(;;) {
		cout << "Please enter a Roman Number:" << flush;
		cin >> tmp;
		if(!tmp)
			break;
		if(tmp < 1 || tmp > maxnum){
			cout << "Illegal input!" << endl;
			cout << "Please enter a number that lies between 1 and 4999." << endl;
                        }
		else {
			cout << "Arabic Number:";
			for(int i = 0 ; i < arraynum ; i++) {
				while(tmp >= romc[i]) {
					tmp -= romc[i];
					cout << romi[i];
				}
			}
			cout << endl;
		}
	}
	return(0);
}

Ich hab mir jetzt nur deinen Compilefehler angeschaut. Ob die Logik passt weiß ich nicht. Damit sollte es jetzt wenigstens compilieren, habs allerdings nicht ausprobiert.

1. Fehler: Strings sind doch viel schöner
2. Fehler: Klammern beim if vergessen

Gruß odigo
 
Danke soweit. Klammern vergessen.. hehe.. das passiert mir oft.

Ich schau mir das mit dem String mal an. Wobei so wie der Code jetzt ist gibt er mir nur noch mehr Fehler als vorher.

Code:
------ Build started: Project: miniproject1, Configuration: Debug Win32 ------
Compiling...
mpr1.cpp
.\mpr1.cpp(28) : error C2784: 'bool std::operator >=(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'int'
        C:\Programme\Microsoft Visual Studio 8\VC\include\string(241) : see declaration of 'std::operator >='
.\mpr1.cpp(28) : error C2784: 'bool std::operator >=(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'int'
        C:\Programme\Microsoft Visual Studio 8\VC\include\string(231) : see declaration of 'std::operator >='
.\mpr1.cpp(28) : error C2784: 'bool std::operator >=(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'int'
        C:\Programme\Microsoft Visual Studio 8\VC\include\string(221) : see declaration of 'std::operator >='
.\mpr1.cpp(28) : error C2784: 'bool std::operator >=(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'int'
        C:\Programme\Microsoft Visual Studio 8\VC\include\xutility(1866) : see declaration of 'std::operator >='
.\mpr1.cpp(28) : error C2784: 'bool std::operator >=(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'int'
        C:\Programme\Microsoft Visual Studio 8\VC\include\utility(101) : see declaration of 'std::operator >='
.\mpr1.cpp(28) : error C2677: binary '>=' : no global operator found which takes type 'const std::string' (or there is no acceptable conversion)
.\mpr1.cpp(28) : fatal error C1903: unable to recover from previous error(s); stopping compilation
Build log was saved at "file://g:\My Projects\miniproject1\miniproject1\Debug\BuildLog.htm"
miniproject1 - 7 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
 
Du hast ab Zeile 27 bis Zeile 30 ein ganz fieses Logikproblem. Das konnte auch vorher nicht funktionieren. tmp ist ein int-Wert und die Elemente aus romc[] sind strings. Mit char romc[] kann das im übrigen auch nicht funktionieren oder weißt du was z.B. 5 - "CM" ist. Denk mal drüber nach. So einfach ist das mit den römischen Zahlen nicht.

Gruß odigo
 
Ja, stimmt. Andersrum ists einfacher. Also arab. in röm. Zahlen konvertieren. Da funktioniert das dann anscheinend auch. Danke jedenfalls für deine Bemühungen soweit.

Muß mal sehen, ob ichs irgendwie anders hinbekomme.

Die haben uns an der Uni kaum was drüber gesagt und dann sind auch noch Vorlesungen ausgefallen :/.

Und jetzt sowas... grml...
Naja, irgendwie werd ichs schon hinkriegen müßen.

Ich hab auf ner anderen Seite noch nen etwas anderen Ansatz gefunden. mit do-while statements. Den schau ich mir jetzt erstmal an.

Wenn jemand nochwas bzgl. der Batchkonvertierung weiß, bitte posten. Ich hab schon bei google und in diversen c/c++ ebooks nachgeschaut und diesbzgl. garnichts gefunden.

Danke.

Aja, hier mal der Code an dem ich mich jetzt versuche (Der ist natürlich nicht so schön wegen der ganzen do-while statements, aber er scheint zu funtionieren):

Code:
#include <iostream>

using namespace std;

void main()

{        int a;
        float b;
        char c;
        cout<<"\nHier werden arabische Zahlen in roemische umgerechnet!";
        
        do                                                                                //Abbruch- oder Wiederholschleife
        {        cout<<"\n\nGib eine Zahl ein:";
                
                do                                                                        //Eingabeschleife
                {        cin>>b;                                                        //Falscheingabe
                        a=(int)b;
                        if (b>8000 || b<1)
                                cout<<"\n\nFalsche Eingabe\n\nGib eine Zahl ein:";
                        else
                        {        if(a!=b)
                                        cout<<"\n\nFalsche Eingabe\n\nGib eine Zahl ein:";
                        }
                }
                while(b>8000 || b<1 || a!=b);                //Roemische Ziffer
                
                cout<<"\nRoemische Zahl:";
                
                do
                {        while (b/1000>=1)
                        {        cout<<"M";
                                b=b-1000;
                        }        
                }
                while(b>1000);

                do
                {        while (b/500>=1)
                        {        cout<<"D";
                                b=b-500;
                        }
                }
                while(b>500);

                do
                {        while (b/100>=1)
                        {        cout<<"C";
                                b=b-100;
                        }
                }
                while(b>100);

                do
                {        while (b/50>=1)
                        {        cout<<"L";
                                b=b-50;
                        }
                }
                while(b>50);

                do
                {        while (b/10>=1)
                        {        cout<<"X";
                                b=b-10;
                        }
                }
                while(b>10);

                do
                {        while (b/5>=1)
                        {        cout<<"V";
                                b=b-5;
                        }
                }
                while(b>5);

                do
                {        while (b/1>=1)
                        {        cout<<"I";
                                b=b-1;
                        }
                }
                while(b>1);
        
                do
                {        cout<<"\n\nNeue Zahl berechnen ?  (j/n) ";
                        cin>>c;
                }
                while((c!='j') && (c!='n'));

        }
        while(c=='j');
}
 
Kurz noch zur Batchbearbeitung. Schau dir mal ofstream und ifstream in Verbindung mit getline an. Einfach mal googlen, da gibts jede Menge Beispiele. So aber jetzt ins Bett :-D

Gruß odigo
 
ok, also.. das hier funktioniert:

Code:
#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
	char roman_num[10];
	cout << "Enter a Roman Numeral: ";
	cin >> roman_num;
	int len = strlen(roman_num);
	int number = 0;
	int counter = 0;
	int b4sum = 0;
	int sum = 0;

	for (counter = len; counter >= 0; counter--)
	{
		if (roman_num[counter] == 'M')
			number = 1000;
		else if (roman_num[counter] == 'D')
			number = 500;
		else if (roman_num[counter] == 'C')
			number = 100;
		else if (roman_num[counter] == 'L')
			number = 50;
		else if (roman_num[counter] == 'X')
			number = 10;
		else if (roman_num[counter] == 'V')
			number = 5;
		else if (roman_num[counter] == 'I')
			number = 1;
		else
			number = 0;

		if (b4sum > number)
			sum = b4sum - number;
		else
			sum = sum + number;

		b4sum = number;
	}

	cout << "The Arabic Numeral is: " << sum << endl;

	return 0;
}

Das Programm, so wie es jetzt ist, konvertiert röm. in arab. Zahlen.
Jetzt müßt ich das nur noch mit der Batchkonvertierung implementieren. Ich hab mal nach den o.g. Begriffen gesucht und auch einiges gefunden. So 100% verstanden hab ichs aber immer noch nicht. Ein Beispiel wäre nicht schlecht. Das Beispiel muß nicht zwangsläufig auf dieses Programm zugeschnitten sein. Sollte halt nur zeigen, wie so ne Batchkonvertierung im c code eingebettet wird.
 
Original von Fifilip
Code:
		if (roman_num[counter] == 'M')
			number = 1000;
		else if (roman_num[counter] == 'D')
			number = 500;
		else if (roman_num[counter] == 'C')
			number = 100;
		else if (roman_num[counter] == 'L')
			number = 50;
		else if (roman_num[counter] == 'X')
			number = 10;
		else if (roman_num[counter] == 'V')
			number = 5;
		else if (roman_num[counter] == 'I')
			number = 1;
		else
			number = 0;

wäre an dieser stelle ein switch-case nicht angebrachter?
 
Zurück
Oben