Hexadezimal



  • canonflux schrieb:

    Wie kann ich das Programm so umwandeln, dass es mir den Hexadezimalwert für verschiedene Basen wie z.B 32 und 12 ausgibt?

    Ähh? Hexadezimal ist immer zur Basis 16.



  • canonflux schrieb:

    Ok ich versuche es verständlich zu erklären 😃

    Ich gebe eine dezimalzahl ein. Diese soll in Hexadezimaldarstellung angezeigt werden. Die gewünschte Basis gebe ich auch ein.

    Beispiel: Die Zahl 1343244 wird dezimal als 1 343 244, im Hexadezimalsystem (B = 16) als 14 7f0c, zur Basis 32 als 1 8voc und zur Basis 12 als 549410 geschrieben.

    Ist das Prinzip des codes richtig für diese Aufgabe?

    Ah, okay.
    Hexadezimal hat btw. die Basis 16 = const.
    strtol kann nur ins Dezimalsystem umwandeln, da wäre itoa etwas für dich:
    http://www.cplusplus.com/reference/cstdlib/itoa/
    Ist glaub ich keine Standardfunktion, ist aber wursch oder?



  • CJosef schrieb:

    strtol kann nur ins Dezimalsystem umwandeln, ....

    strtol wandelt ins interne Format. Meist ist dies das Dual/Binaersystem.

    printf (oder itoa) wandelt das dann in ein für Menschen gut lesbares Format um. Meist das Dezimalsystem.
    Aber ob Dezimal-, Hexadezimal oder was auch immer, es ist nur eine andere Darstellung des selben Wertes.



  • #include <stdio.h>
    #include <stdlib.h>
    
    int main ( void )
    {
    	char buf[256];
    	int number, base, base_min = 2, base_max = 36;
    	printf ( "Enter a decimal number to convert: " );
    	if ( 1 == scanf("%d", &number))
    		for ( base = base_min; base <= base_max; base++ )
    			printf ( "base: %2d number: %s\n", base, itoa ( number, buf, base ));
    	return 0;
    }
    


  • Warnung: Die folgende Lösung könnte für Sie schädlich sein (Original-Zitat).
    Häufige Nebenwirkunge sind Verständnislosigkeit, Depressionen und Angstzustände

    /*A031C_Basiswandler.cpp: Einstiegspunkt der Konsolenanwendung.*/
    /*Einfacher Basiswandler fuer Ganzzahlen*/
    
    #include <stdio.h>
    #include <stdlib.h> /*fuer system*/
    #include <string.h> /*fuer _strrev*/
    
    #ifdef __cplusplus
      #pragma message("mit C++")
    #else
      #pragma message("mit C")
    #endif
    
    void wandleIterativ(unsigned long nD,unsigned long nBasis) {
      char cErgebnis[80+1];
      /*_strset(cErgebnis,NULL); /*Angstanweisung*/
      unsigned char cZ,nI=0;
      while (nD>0) { /*Iteration*/
        cZ=(unsigned char)((nD%nBasis)+48); /*Ziffer*/
        if (cZ>57) cZ+=7; /*Buchstabe*/
        nD/=nBasis;
        cErgebnis[nI++]=cZ; /*hinten anhängen*/
      } /*while*/
      cErgebnis[nI]='\0';
      fprintf_s(stdout,"\nErgebnis zur Basis %lu: %s\n\n",nBasis,_strrev(cErgebnis));
    } /*wandleIterativ*/
    
    void wandleRekursiv(unsigned long nD,unsigned long nBasis) {
      unsigned char cZ;
      if (nD!=0) {
        cZ=(unsigned char)((nD%nBasis)+48); /*Ziffer*/
        if (cZ>57) cZ+=7; /*Buchstabe*/
        fprintf_s(stdout,"%c",cZ);
        wandleRekursiv(nD/nBasis,nBasis);
      } /*if*/
    } /*wandleRekursiv*/
    
    int main() {
      unsigned long nD,nBasis;
      do {
        fprintf_s(stdout,"Dezimale Ganzzahl: ");fflush(stdin);scanf_s("%ul",&nD);
      } while (nD>LONG_MAX); /*scanf ignoniert u, wandelt also in l, Test mit -1*/
      do {
        fprintf_s(stdout,"Zielbasis 2-36:   ");fflush(stdin);fscanf_s(stdin,"%ul",&nBasis);
      } while (nBasis<2||nBasis>36);
      wandleIterativ(nD,nBasis); /*Reihenfolge wird intern korrigiert*/
      fprintf_s(stdout,"Rekursions-Ergebnis in umgekehrter Reihenfolge: ");
      wandleRekursiv(nD,nBasis); /*Rekursion erzeugt die Ziffern in umgekehrter Reihenfolge*/
      fprintf_s(stdout,"\n\n");
      system("Pause");
      return 0;
    } /*main*/
    

    Beispiele auf der Konsole

    Dezimale Ganzzahl: 1343244
    Zielbasis 2-36:   16
    
    Ergebnis zur Basis 16: 147F0C
    
    Rekursions-Ergebnis in umgekehrter Reihenfolge: C0F741
    
    Drücken Sie eine beliebige Taste . . .
    
    Dezimale Ganzzahl:  1343244
    Zielbasis 2-36:   36
    
    Ergebnis zur Basis 36: SSGC
    
    Rekursions-Ergebnis in umgekehrter Reihenfolge: CGSS
    
    Drücken Sie eine beliebige Taste . . .
    


  • DirkB schrieb:

    CJosef schrieb:

    strtol kann nur ins Dezimalsystem umwandeln, ....

    strtol wandelt ins interne Format. Meist ist dies das Dual/Binaersystem.

    printf (oder itoa) wandelt das dann in ein für Menschen gut lesbares Format um. Meist das Dezimalsystem.
    Aber ob Dezimal-, Hexadezimal oder was auch immer, es ist nur eine andere Darstellung des selben Wertes.

    Ja, stimmt. Ich weiß, ich denke da nur nicht immer dran.
    Meistens ist es das Dual-/Binärsystem wenns nicht gerade der russische
    Setun-Computer ist, der im Ternärsystem, http://de.wikipedia.org/wiki/Setun
    oder der biologische Computer der Ansala, der im Quartärsystem (Science Fiction Adventure 🤡 ) arbeitet.
    Alles frisch gegoogelt 😃



  • Waldschrat schrieb:

    Warnung: Die folgende Lösung könnte für Sie schädlich sein (Original-Zitat).
    Häufige Nebenwirkunge sind Verständnislosigkeit, Depressionen und Angstzustände

    Ja, bei dem Code, kein Wunder! 😃 (scnr)
    Sprichst du aus Erfahrung? 😮



  • Schreib doch bitte bei deinen nächsten Programmen noch dazu mit welchem Compiler, Betriebssystem und Codepages du das Programm compilierst.

    Neben bei ist hier das Unterforum für Standard-C. Da gibt es Funktionen wie _strrev nicht. 😞

    Und wenn du '0' meinst, dann schreib auch '0' hin und nicht 48

    Tipp: wenn du die Ausgabe in wandleRekursiv nach dem rekursiven Aufruf machst, ist die Reihenfolge auch richtig.



  • Ich versuche das mit itoa () zu lösen, aber leider erkennt mein Compiler den nicht.

    Hab mal bisschen geguckt und das hier als Ersatzfunktion gefunden:

    char *my_itoa(int wert, int laenge) {
        char *ret =(char *) malloc(laenge+1 * sizeof(char));
        int i;
    
        for(i  =0; i < laenge; i++) {
            ret[laenge-i-1] = (wert % 10) + 48;
            wert = wert / 10;
        }
        ret[laenge]='\0';
        return ret;
    }
    

    Kann ich das verwenden? Wenn ja, wie verhält es sich mit den Werten, die ich in der Funktion verwende. Ich kann ja in die Funktion nur 2 (myitoa(x,y)) Variablen statt 3 (itoa (x,y,z)) einbinden.



  • Erkennt er nicht? Hmmm ... welchen Compiler hast du?
    Bei mir ist die Funktion in stdlib.h deklariert.
    Vllt. ist es bei dir eine andere Headerdatei.



  • Die Funktion wird dir nicht viel nützen, da dort die Basis fest auf 10 eingestellt ist.
    Das Problem für dich wird wohl die Darstellung der Buchstaben sein.

    Zudem wird in der Funktion Speicher per malloc angefordert, den du dann ausserhalb der Funktion wieder freigeben musst.
    Das ist schlechtes Design.



  • itoa gehört nicht zum Standard von C.
    Deswegen heißt sie manchmal auch _itoa() (mit einem _ davor)



  • CJosef schrieb:

    Erkennt er nicht? Hmmm ... welchen Compiler hast du?
    Bei mir ist die Funktion in stdlib.h deklariert.
    Vllt. ist es bei dir eine andere Headerdatei.

    Ich benutze gcc auf Linux. Scheint es nicht zu geben. Gibt es eine andere Alternative für itoa?


  • Mod

    canonflux schrieb:

    Gibt es eine andere Alternative für itoa?

    Warum lernst du denn programmieren? Juckt es dich nicht in den Fingern, das selber zu schreiben? Ist nicht schwer. Ich hätte es dir hier längst vorgemacht, wenn ich nicht der Meinung wäre, dass du ohne Komplettlösung wesentlich mehr lernen würdest. Hier ein Tipp, um die einzige Schwierigkeit (die Mischung aus Zahlen und Buchstaben) zu überwinden:

    const char* ziffern = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
    // Somit gilt:
    ziffern[0] == '0';
    ziffern[5] == '5';
    ziffern[10] == 'A';
    ziffern[16] == 'G';
    


  • canonflux schrieb:

    Ich benutze gcc auf Linux. Scheint es nicht zu geben. Gibt es eine andere Alternative für itoa?

    Hier gibts ein paar Anregungen:

    http://www.jb.man.ac.uk/~slowe/cpp/itoa.html

    viele grüße
    ralph



  • rkhb schrieb:

    canonflux schrieb:

    Ich benutze gcc auf Linux. Scheint es nicht zu geben. Gibt es eine andere Alternative für itoa?

    Hier gibts ein paar Anregungen:

    http://www.jb.man.ac.uk/~slowe/cpp/itoa.html

    viele grüße
    ralph

    Das sind Komplettlösungen 😃



  • char* uitoa ( unsigned number, char* buf, int base )
    {
    	char digits[] = "0123456789ABCDEFGHIJLKMNOPQRSTUVWXYZ";
    	char stack [ 256 ];
    	int i = 0, j = 0;
    	while ( number )
    		stack [ i++ ] = digits [ number % base ], number /= base;
    	buf [ i ] = 0;
    	while ( i > 0 )
    		buf [ j++ ] = stack [ --i ];
    	return buf;
    }
    
    int main ( void )
    {
    	char buf [ 256 ];
    	unsigned base, number;
    	if ( 1 == scanf ( "%u", &number ))
    		for ( base = 2; base < 37; base++ )
    			printf ( "%s(%u)\n", uitoa ( number, buf, base ), base );
    	return 0;
    }
    

    http://ideone.com/0Hosqk
    :p
    Edit:
    Schöner wäre es wohl, die Puffer so zu deklarieren:

    char stack [ sizeof ( unsigned ) * CHAR_BIT ];
    char buf [ sizeof ( unsigned ) * CHAR_BIT + 1 ];
    


  • Inzwischen bin ich von einigen Gurus dieses Forums heftig zusammengestaucht worden. Leider gibt es nicht einen konkreten Hinweis, was an den Programmen falsch ist.
    Nur um den Beitragszähler täglich zu erhöhen, sollten keine solche Bemerkungen fallen.
    Leider habe ich das Gefühl, dass einige Gurus noch wie im letzten Jahrtausend programmieren.

    Es ist doch einfach, den Quelltext in andere Kompiler zu übertragen und auszuprobieren. Welche Fehlermeldungen gibt es dann? In welchen Situationen funktionieren die Programme nicht.

    Hier also mein Profil:

    Ich setze Visual Studio C und C++ ein. Ich schalte bewusst bei allen Programmen die Kompilerschalter zwischen beiden Varianten hin- und her.

    Ich beseitige alle Warnungen, auch diejenigen, die mir ein Casting bei malloc, calloc, realloc usw. empfehlen.

    Ich versuche meine Programme insbesondere an den Intervallgrenzen zu testen.

    Ich benutze (hoffentlich) immer die neuen, gesicherten Funktionen mit dem Postfix _s, also printf_s, scanf_s, strcpy_ und wie sie alle heißen (natürlich in der Norm verzeichnet).

    Ich arbeite immer mit der Angabe der Standardströme, um beispielsweise zwischen stdout und stderr sauber zu trennen.

    Ich würde gerne zum Beispiel wissen, warum alle Einsender sofort zusammengestaucht werden, wenn sie malloc casten. Meine Gründe für ein sauberes Casting sind:

    1. Mein Kompiler warnt mich sinnvollerweise.
    2. C ist eine (angeblich) typsichere Sprache. void * ist doch alles, also ein großer Speichermatsch.
    3. Ich gebe mit dem Casten dem Kompiler bereits grundlegende Fehler beim Übersetzen zu erkennen.
    4. Die OOP hat bewusst die "erweiterte Typkompatibilität" eingeführt, um das Casten zwischen verschiedenen Hierarchieebenen zu erlauben.
    5. C versucht "krampfhaft" diese Fähigkeiten durch "typlose" Zeiger zu simulieren. Das muss kein Anfänger lernen.
    6. Moderne Sprachen wie Java und C# haben es als große Errungenschaft (ich glaube so um 2003) gepriesen, dass sie jetzt typsichere, generische Datentypen wie Listen usw. eingeführt haben.



  • Waldschrat schrieb:

    Ich würde gerne zum Beispiel wissen, warum alle Einsender sofort zusammengestaucht werden, wenn sie malloc casten.

    http://www.c-plusplus.net/forum/viewtopic.php?t=206606



  • Waldschrat schrieb:

    Ich benutze (hoffentlich) immer die neuen, gesicherten Funktionen mit dem Postfix _s, also printf_s, scanf_s, strcpy_ und wie sie alle heißen (natürlich in der Norm verzeichnet).

    Welche Norm soll das sein, die Microsoft'sche Norm?


Anmelden zum Antworten