Umrechnen von Hexzahlen
-
wäre froh wenn ich schon einen eigenen Stil hätte. das alles habe ich aus dem Buch. Werde das mal ausprobieren was du mir geschrieben hast.. hoffe ich bekomme das hin.. vielen dank an dieser Stelle..
gruß
-
Hi Mimas,
da Du noch Anfänger zu sein scheinst, noch mal ein leichter OT-Tipp von mir:
Mimas schrieb:
...
if(iEingabe != '\n') { if(isxdigit((char) iEingabe)) { if(iEingabe == 'A') { iAusgabe = 10; } else if(iEingabe == 'B') { iAusgabe = 11; } else if(iEingabe == 'C') { iAusgabe = 12; } else if(iEingabe == 'D') { iAusgabe = 13; } else if(iEingabe == 'E') { iAusgabe = 14; } else if(iEingabe == 'F') { iAusgabe = 15; } else { iAusgabe = iEingabe - 48; } printf("Der Wert ist: %d", iAusgabe); } else { printf("Iss nisch hex-zahl"); } } } }
...
geht sehr viel einfacher z.B. per "switch-case":
iAusgabe = -1; switch(iEingabe) { case '\n' : break; case 'A': iAusgabe = 10; break case 'B': iAusgabe = 11; break; case 'C': iAusgabe = 12; break; case 'D': iAusgabe = 13; break; case 'E': iAusgabe = 14; break; case 'F': iAusgabe = 15; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': iAusgabe = iEingabe - 48; break; default: printf("Iss nisch hex-zahl"); } if(iAusgabe != -1) printf("Der Wert ist: %d", iAusgabe);
Die "if-else-Schachtelei" wird bei Vergleich gegen Strings und "variable Ausdrücke" notwendig, aber für so feste Vergleichswerte wie hier, ist switch-case ganz praktisch/übersichtlich.
Aber wie schon gesagt: Wenn es nur um die Problemlösung geht, gibt es auch vorgefertigte Lösungen...
Gruß,
Simon2.
-
Hallo Simon2,
bin gerade dabei mir das Thema switch/case anzueigenen.. Finde die Variante wie du sie aufgeführt hast auch besser..
Wenn ich die erste Variante (if-else) fertig habe, versuche ich das Programm mal mit deinem Tipp, neu zu gestalten.
Vielen herzlichen dank Simon2..
Gruß,
Mimas
-
Simon2 schrieb:
case '9': iAusgabe = iEingabe - 48; break;
Schreibt doch lieber '0' statt der 48, da sieht man sofort was gewollt ist...
<pedantic>
... und außerdem ist nicht unbedingt garantiert, dass die '0' den Dezimalwert 48 hat, auch wenn das auf den meisten Systemen der Fall ist
</pedantic>
-
<nochpedantischer>
Und 'A'-'F' könnte man ebenso zusammenfassen, mit iEingabe - 'A' + 10 (sogar in EBCDIC :D)
</nochpedantischer>
-
Ich habe das ganze jetzt mal ein wenig umgeschrieben.. habe eure Tipps erstmal außen vor gelassen und mein "Ursprungsprogramm" genommen.. eine neue Versoin schreibe ich wenn das hier funktioniert.
Hier der Code.
#include <stdio.h> #include <ctype.h> #include <math.h> #include <stdlib.h> #include <string.h> #define BASIS 16 // Basis bzw. Zähler #define MAXCHAR 100 // maximale Zeichen void main() { char hex[MAXCHAR]; // für Hex-Eingabe char zeichen; // Zeichen double dezimalzahl = 0; // Gesamtsumme, am Ende ausgegebene Dezimalzahl int arrayende = 0; // neues Array-Ende int nenner = 0; // Nenner int summand = 0; // einzelner Summand int iZaehler = 0; // Zähler int iAusgabe; arrayende = nenner = summand = iZaehler = 0; // Zeichen einlesen und überprüfen, ob es Hex-Ziffern sind. // neues Array-Ende setzen for (iZaehler = 0; iZaehler <=MAXCHAR && (zeichen=getchar()) != EOF; iZaehler++) { if (zeichen != '\n' && !isxdigit(zeichen)) { printf("Keine Hex-Ziffer an der Stelle %d\n", iZaehler + 1); exit(0); } if (zeichen == '\n') { hex[iZaehler] = '\0'; arrayende = iZaehler - 1; } else { hex[iZaehler] = zeichen; } } // Array von hinten beginnend auslesen; // Die Werte in den entsprechenden // Dezimal-Wert umwandeln. // Dezimal-Zahl ausgeben for (iZaehler = arrayende; iZaehler >= 0; iZaehler--) { if (hex[iZaehler] == 'A') { iAusgabe = 10; } else if (hex[iZaehler] == 'B') { iAusgabe = 11; } else if (hex[iZaehler] == 'C') { iAusgabe = 12; } else if (hex[iZaehler] == 'D') { iAusgabe = 13; } else if (hex[iZaehler] == 'E') { iAusgabe = 14; } else if (hex[iZaehler] == 'F') { iAusgabe = 15; } else { iAusgabe = hex[iZaehler] - '0'; } summand = (iAusgabe * (pow(BASIS,nenner))); nenner++; dezimalzahl += summand; // Jedoch wird mir das hier nicht klar?? warum "+=" } // Weiß jemand Rat? printf("Dezimal-Zahl: %0.f", dezimalzahl); }
Jedoch fehlt mir das Verständnis für die letzten Zeilen. Habe das mit der Funktion pow aus einem anderen Programm rauskopiert.
Gruß,
Mimas
-
Erstens: pow() berechnet die Potenz einer Zahl (aber es ist imho schneller, du fängst vom anderen Ende der Eingabe an und schiebst die Zahl stückweise nach oben - siehe mein Beitrag weiter oben.
Zweitens: += ist eine kombinierte Zuweisung (die gibt's für fast alle Operatoren) und vereinigt = und + zu einer Operation (die Zeile ist äquivalent zu
dezimalzahl=dezimalzahl+summand;
)Drittens: Warum das Rad immer neu erfinden? Anstelle der Eingabeschleife kannst du auch vorgefertigte Funktionen verwenden (z.B. fgets()).
-
LordJaxom schrieb:
<nochpedantischer>
Und 'A'-'F' könnte man ebenso zusammenfassen, mit iEingabe - 'A' + 10 (sogar in EBCDIC :D)
</nochpedantischer><extrempedantisch>
Es ist nicht garantiert, dass das Alphabet in seiner Reihenfolge durchdummeriert wird
</extrempedantisch>
-
Ich würde diese Funktion gerne nehmen, nur muss ich mich Schritt für Schritt an C heran arbeiten. Sprich mein Ausbilder erlaubt es mir immer nur das zu nehmen, was ich auch schon kenne bzw. wie weit ich im Buch bin..
Cstoll du bist Spitze!
-
TactX schrieb:
Simon2 schrieb:
case '9': iAusgabe = iEingabe - 48; break;
Schreibt doch lieber '0' statt der 48, da sieht man sofort was gewollt ist...
<pedantic>
... und außerdem ist nicht unbedingt garantiert, dass die '0' den Dezimalwert 48 hat, auch wenn das auf den meisten Systemen der Fall ist
</pedantic>Das ist mir vollkommen klar und gerade bei solche Sachen muss ich hier sogar portabel programmieren (und würde das deswegen überhaupt nicht so machen).
Ich wollte ihm als Anfänger nur mal das "switch" zeigen ... und das erkennt er am Besten, wenn ich sonst möglichst wenig an seinem Programm ändere (OK, die endl- und die isxdigit()-Abfragen habe ich auch gleich mit reingepult - aber auch das diente der Demonstration vom switch).Gruß,
Simon2.
-
Bezog sich auch nicht speziell auf dich
-
TactX schrieb:
Bezog sich auch nicht speziell auf dich
Ach soooo.
(Immerhin hast Du auch den Imperativ Plural verwendet, wie mir erst jetzt auffiel).
Gruß,
Simon2.
-
Hallo nochmal,
erstmal vielen dank für die zahlreichen und wirklichen guten Beiträge von gestern.
Habe das Programm auch erfolgreich mit euren Tipps "umgeschrieben".
Nur muss ich heute vor Feierabend meinem AUsbilder das "Ursprungs-Programm" zeigen.
Nun habe ich folgende Frage.
Alles funktioniert so wie ich will, jetzt muss ich aber noch einbauen das ich in der Eingabe z.B. ein "0x" oder "0X" davor setzen kann.
Ungefähr so: 0xAF oder ähnlich
Hier der Code:
#include <stdio.h> #include <ctype.h> // Bibliothek für die Funktion isxdigit #include <math.h> // Bibliothek für die Funktion pow #define BASIS 16 // BASIS (später für die Rechnung) #define MAXCHAR 100 void main() { char hex[MAXCHAR]; // für Hex-Eingabe char cEingabe; // Eingabevariable double dezimalzahl = 0; // Umgerechnete Dezimalzahl int iArray = 0; // neues Array-Ende int nenner = 0; // Nenner int summand = 0; // einzelner Summand int iZaehler = 0; // Zähler int iAusgabe; for (iZaehler = 0; iZaehler <=MAXCHAR && (cEingabe=getchar()) != EOF; iZaehler++)// Zeichen werden eingelesen { // überprüfen ob es sich um eine if (cEingabe != '\n' && ! isxdigit(cEingabe)) // Hex-Ziffer handelt! { printf("Keine Hex-Ziffer eingegeben! %d\n", iZaehler); } if (cEingabe == '\n') { hex[iZaehler] = '\0'; iArray = iZaehler - 1; } else { hex[iZaehler] = cEingabe; } } for (iZaehler = iArray; iZaehler >= 0; iZaehler--) // Array auslesen. { // Hex-Ziffern in entsprechende Dezimalzahl umwandeln if (hex[iZaehler] == 'A') // und ausgeben. { iAusgabe = 10; } else if (hex[iZaehler] == 'B') { iAusgabe = 11; } else if (hex[iZaehler] == 'C') { iAusgabe = 12; } else if (hex[iZaehler] == 'D') { iAusgabe = 13; } else if (hex[iZaehler] == 'E') { iAusgabe = 14; } else if (hex[iZaehler] == 'F') { iAusgabe = 15; } else { iAusgabe = hex[iZaehler] - '0'; // Ziffern von 0 bis 9 } summand = (iAusgabe * (pow(BASIS, nenner))); nenner++; dezimalzahl = summand; } printf("Dezimal-Zahl: %0.f", dezimalzahl); }
Hatte mir gedacht das in etwa so einzubauen:
if(hex[iZaehler] == 0) { iAusgabe = ' '; } else if(hex[iZaehler] == 'x' || hex[iZaehler] == 'X') { iAusgabe = ' '; }
Nur ist dann das Problem, das ich ein Fehler bekomme, wenn ich eine 0 an dritter Stelle eingebe.
Hat jemand einen Tipp für mich wie ich das einbinde das nur die ersten 2 Stellen berücksichtigt werden?
Gruß
Mimas
-
Du kannst vor der eigentlichen Rechenschleife eine Spezialüberprüfung vorsetzen:
if(hex[0]=='0' && toupper(hex[1]=='X') ende=2; else ende=0; ... for (iZaehler = iArray; iZaehler >= ende; iZaehler--) // Array auslesen. ...
-
Gibt es auch eine Möglichkeit das toupper wegzulassen? darf das eigentlich noch nicht benutzen?
Wasrum hast du hex[l] genommen?Gruß
Mimas
-
Mimas schrieb:
Gibt es auch eine Möglichkeit das toupper wegzulassen? darf das eigentlich noch nicht benutzen?
Ja:
(hex[1]=='X'||hex[1]=='x')
Wasrum hast du hex[l] genommen?
Wenn die Eingabe eine Hex-Kennung (0x...) enthält, dann steht sie in den ersten beiden Zeichen deines Eingabestrings (in hex[0] die '0' und in hex[1] das 'x')
-
CStoll, du hast mir meinen A... gerettet!
Vielen dank und noch einen schönen :xmas1: Nikolaus! :xmas1: