Zahlensystem - Basis konvertieren



  • Hallo zusammen,
    ich möchte ein Programm erstellen, womit ich eine zahl beliebiger Basis in eine neue Basis konvertieren kann.
    der code, den ich geschrieben hat, ist natürlich noch nicht vollständig, aber ich kann mir im moment nicht erklären, warum eine konvertierung von zB:
    12012 (basis 3) zur basis 10 noch nicht klappt.

    Es kommt auch kein Fehler, keine Warnung, nur wenn ich das Programm starte, stürzt es gleich wieder ab.

    Ich hoffe, jemand kann mir helfen,
    Gruß

    Hier der Code

    include <iostream>
    using namespace std;
    
    int exp(int base,int exponent) //exponential function
    { int result,i;
    	if(exponent==0)
    		result=1;
    
    	else if (exponent=1)
    		result=base;
    
    	for(i=1;i<exponent;i++)
    		{
    		  result=base*result;
    		}
    	return result;
    }
    
    int arbitToDec (char value[], int oldBase ) //converting to the decimal system
    {
    	int length=strlen(value), result=0;
    
    	for (int i=0; i<length; i++)
    	{
    		if (value[i] >= '0' && value[i] <= '9'  )
    			result=(exp(oldBase,(length-i-1)))*((value[i]-'0')+result);
    
    		else if (value[i] >= 'a' && value[i] <= 'z')
    			result=exp(oldBase,(length-i-1))*(value[i]-'a'+10)+result;
    
    		else if (value[i] >='A' && value[i] <='Z')
    			result=exp(oldBase,(length-i-1))*(value[i]-'A'+10)+result;
    
    	}
    
    	return result;
    }
    
    // converting from the decimal to an arbitrary system
    int decToArbit (int value, int newBase )
    
    { int tempVal[32], newLength=0;
    
    	for (int i=0;tempVal!=0;i++)
    	{
    	tempVal[i]=value%newBase;
    	value=value/newBase;
    	newLength++;
    
    	}
    
    	for(int i=0;i<newLength;i++)
    	{
    
    	cout << tempVal[i]; 
    	}
    	return 0;
    }
    
    void main ()
    {	char value[32];
    	int oldBase=0, newBase, valueInDec=arbitToDec(value, oldBase);
    
    	cout << endl << "Please, enter a Number that you want to convert in a base ranging from 2 to 36!" << endl;
    	cin >> value;
    
    	cout << "What is the base of this number?" << endl;
    	cin >> oldBase;
    
    	cout << "In what base should your number be converted? Please, choose a base ranging from 2 to 36!" << endl;
    	cin >> newBase;
    
    	cout << "The number  " << value << "  in the base  " << oldBase << "  is  " << decToArbit(valueInDec, newBase) << "  in base  " << newBase << endl;
    
    	//arbitToDec(value.c_str(), oldBase)
    
    	system("pause");
    
    	//return 0;
    
    }
    

  • Mod

    valueInDec=arbitToDec(value, oldBase);
    

    value zeigt an der Stelle auf uninitialisierten Speicher. Deshalb passiert etwas undefiniertes, z.B. ein Absturz.

    Dies zu behben wird dein jetziges Problem lösen. Und dich vermutlich direkt zum nächsten Problem bringen, denn der Code sieht dermaßen unsauber aus, dass ich mir nicht vorstellen kann, dass er funktioniert. Du solltest versuchen, alles nochmal gründlich zu überarbeiten.



  • SeppJ schrieb:

    valueInDec=arbitToDec(value, oldBase);
    

    value zeigt an der Stelle auf uninitialisierten Speicher. Deshalb passiert etwas undefiniertes, z.B. ein Absturz.

    Dies zu behben wird dein jetziges Problem lösen. Und dich vermutlich direkt zum nächsten Problem bringen, denn der Code sieht dermaßen unsauber aus, dass ich mir nicht vorstellen kann, dass er funktioniert. Du solltest versuchen, alles nochmal gründlich zu überarbeiten.

    Vielen Dank für die Antwort. Aber habe ich das nicht in genau der Zeile dadrüber mit ( char value [32] ) gemacht? war zumindest mein vorhaben 🙂

    Dass das alles noch so unsauber ist stimmt natürlich, ich wollts erstmal zum laufen bringen und denn aufräumen.

    Vielen Dank


  • Mod

    JP001 schrieb:

    Vielen Dank für die Antwort. Aber habe ich das nicht in genau der Zeile dadrüber mit ( char value [32] ) gemacht? war zumindest mein vorhaben 🙂

    In der Zeile davor steht, was value für ein Typ ist und es wird Speicherbereich für value reserviert. Aber in diesem Speicherbereich steht irgendwas. Zumindest kein nullterminierter CString wie es deine Funktion erwartet.

    Du könntest übrigens statt des char Arrays lieber std::string benutzen. Dein Programm wird dadurch flexibler und du musst auf weniger Fehlerquellen wie diese achten (eigentlich auf gar keine mehr). Dafür musst du natürlich ein paar Sachen umschreiben aber ich wage mal vorherzusehen, dass die vieles sowieso noch mal neu schreiben musst.



  • Hi,

    ich hab nur mal fix meine alten Sources durch gesehen, weil ich das auch mal fgemacht hatte, hier ein knapper Ausschnitt:

    typedef enum {
    
    	BIN =  2,
    	OCT =  8,
    	DEC = 10,
    	HEX = 16
    
    } BASE;
    
    // Converter
    int converter( char *szBuffer, const int iSize, unsigned long ulValue, BASE base ) {	
    
    const char cDigits[ ] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
    						  'A', 'B', 'C', 'D', 'E', 'F' };         
    	// Clear buffer
    	for( int i = 0; i < iSize; i++ )
    		szBuffer[ i ] = 0;
    
    	// Indexposition
    	int iIndex = iSize - 1;
    
    	szBuffer[ iIndex-- ] = '\0';
    
    	do {
    
    		szBuffer[ iIndex-- ] = cDigits[ (ulValue % base) ];
    
    		ulValue /= base;
    
    	} while( ulValue > 0 );
    
    	return iIndex + 1;
    }
    

    Hoffe es hilft.

    [EDIT]:

    Achja noch als Bemerkung, die umgerechnete Zahle in das jeweilige System, wird im Buffer von der letzten Zelle nach vorn geschrieben, der Returnwert, liefert also den Index des ersten Wertes im Buffer.

    Lg Tobi



  • Vielen Dank tobi!
    Ein bisschen hilfts, aber ich glaub du hast da ein paar dinge eingebaut, von denen ich noch nie was gehört habe. Ich hab mich nochmal rangesetzt und versucht die Fehler zu korrigieren.
    So, wie es im Moment ist, gibt es beim kompilieren keine fehler, jedoch beim verlinken:

    error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl outstring(char)" (?outstring@@YA?AV?basic_string@DU?basic\_string@DU?char_traits@D@std@@V?$allocator@D@2@@std@@D@Z)" in Funktion ""void __cdecl decToArbit(int,int)" (?decToArbit@@YAXHH@Z)".

    fatal error LNK1120: 1 nicht aufgelöste externe Verweise.

    Hier ist mein aktueller Code

    [code]
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    void exeSysChange(char value[], int oldBase, int newBase);
    void error(char value[], int oldBase, int newBase);
    int exp(int base, int exponent);
    int arbitToDec(char value[], int oldBase);
    void decToArbit(int value, int newBase);
    //void out(char value[], int newBase);
    void main()
    {
    int oldBase=0, newBase=0;
    char value[32];
    
    	cout << endl << "Please, enter a Number that you want to convert in a base ranging from 2 to 36!" << endl;
    	cin >> value;
    
    	cout << "What is the base of this number?" << endl;
    	cin >> oldBase;
    
    	cout << "In what base should your number be converted? Please, choose a base ranging from 2 to 36!" << endl;
    	cin >> newBase;
    
    	error(value, oldBase, newBase);
    	//exeSysChange(value, oldBase, newBase);
    
    }
    void error(char value[], int oldBase, int newBase)
    {	int i=0;
    
    	if (value[i]-'0'>=oldBase || value[i]-'a'+10>=oldBase || value[i]-'A'+10>=oldBase )
    		{
    		cout << "wrong input! At least one digit of the input is too large for base!" << endl;
    		main();
    		}
    	else if (oldBase<2 || oldBase>36 || newBase<2 || oldBase>36)
    		{
    		cout << "wrong input! Permissable bases range from 2 to 36 !" << endl;
    		main();
    		}
    	else
    		{
    		exeSysChange(value, oldBase, newBase);
    		}
    
    }
    void exeSysChange(char value[], int oldBase, int newBase)
    {
    	int valueInDec=arbitToDec(value, oldBase);
    	//char newValue[32];
    cout << "zwischenergebnis:  " << valueInDec << endl;
    system("pause");
    	decToArbit(valueInDec, newBase);
    	//out(newValue, newBase);
    
    }
    int exp(int base,int exponent) 
    { int result,i;
    	if(exponent==0)
    		result=1;
    
    	else if (exponent=1)
    		result=base;
    
    	for(i=1;i<exponent;i++)
    		{
    		  result=base*result;
    		}
    	return result;
    } 
    int arbitToDec(char value[], int oldBase ) //converting to the decimal system
    {
    	int length=strlen(value), result=0, i=0;	
    
    	for (int i=0; i<length; i++)
    		{
    			if (value[i] >= '0' && value[i] <= '9'  )
    				result=(exp(oldBase,(length-i-1)))*((value[i]-'0')+result);
    
    			else if (value[i] >= 'a' && value[i] <= 'z')
    				result=exp(oldBase,(length-i-1))*(value[i]-'a'+10)+result;
    
    			else if (value[i] >='A' && value[i] <='Z')
    				result=exp(oldBase,(length-i-1))*(value[i]-'A'+10)+result;
    		}
    	return result;
    }
    void decToArbit(int value, int newBase )
    
    { int tempVal[32], newLength=0;
    
    	for (int i=0;tempVal!=0;i++)
    		{
    		tempVal[i]=value%newBase;
    		value=value/newBase;
    		newLength++;
    		}
    
    	for(int i=0;i<newLength;i++)
    		{
    		string outstring(char(tempVal));
    		cout << "The number in " << newBase << "is" << outstring << endl;
    		//cout << char(tempVal[i]);
    
    		}
    
    }
    

    [/code]

    Vielleicht hat ja noch jemand einen Ratschlag, das wäre nett.
    an der stelle

    [code]
    cout << "zwischenergebnis:  " << valueInDec << endl;
    system("pause");
    

    [/code]

    Wollte ich mal schaun, ob wenigstens die umrechnung ins dezimalsystem geklappt hat. Doch davor kommt wie gesagt der Fehler beim verlinken...

    Lieben Gruß
    JP


Anmelden zum Antworten