htoi() - hex- zu dez-Werten wandeln
-
Probe-Nutzer schrieb:
schon mal daran gedacht, daß es hier um "K & R - C" geht
Also bei mir zeigt der Forumtitel, dass es um ANSI C (bzw. ISO C) geht.
Probe-Nutzer schrieb:
da gibt es keinen bool-Datentyp
In ISO C schon (-> stdbool.h).
Probe-Nutzer schrieb:
man sollte sich in der Lernphase auch mit den #define's auseinandersetzen, das wird man noch häufig genug in C-Code finden
Das stimmt schon, nur solltest du Makros nicht überstrapazieren und nur dort verwenden, wo es Sinn macht.
-
@interpreter
hab erst jetzt gesehen das du noch weiterspielen wolltest
da geh ich natürlich drunterint h(char*c){int j=0;for(;*c;j=j<<4|*c++-48-7*(*c>57)&15);return j;}
-
Probe-Nutzer schrieb:
schon mal daran gedacht, daß es hier um "K & R - C" geht
groovemaster2002 schrieb:
Also bei mir zeigt der Forumtitel, dass es um ANSI C (bzw. ISO C) geht.
aha, wieder jemand, der jeden möglichen Interpretationsspielraum nutzt, wenn man ihm die Gelegenheit dazu gibt
, dann schalte ich mal, wenn auch ungern, den Haarspaltungs-Modus ein:
mir ist meistens klar, in welchem Forum ich mich befinde, auch dieses Mal war es so, mit hier war in meiner Antwort gemeint: in diesem Beitrags-Thread.
Probe-Nutzer schrieb:
da gibt es keinen bool-Datentyp
groovemaster2002 schrieb:
In ISO C schon (-> stdbool.h).
auch das ist mir bekannt, nur in den K & R-Ausgaben, die sowohl cHillb3rT als auch /bin/bash0R als Lehrbuch verwenden, wird man diesen Datentyp evtl. vergeblich suchen.
Probe-Nutzer schrieb:
man sollte sich in der Lernphase auch mit den #define's auseinandersetzen, das wird man noch häufig genug in C-Code finden
groovemaster2002 schrieb:
Das stimmt schon, nur solltest du Makros nicht überstrapazieren und nur dort verwenden, wo es Sinn macht.
ganz meine Meinung
bitte nicht falsch verstehen, aber ich wollte nur klar stellen, wie es gemeint war, womit ich den Haarspaltungs-Modus wieder ausschalte
MfG
-
Windalf schrieb:
@interpreter
hab erst jetzt gesehen das du noch weiterspielen wolltest
da geh ich natürlich drunterint h(char*c){int j=0;for(;*c;j=j<<4|*c++-48-7*(*c>57)&15);return j;}
Ich hab grad noch ne rekursive Fassung geschrieben, aber die is viel zu lange
int h(char*s,int i, int j){return i>=0?(s[i]>57?(s[i]&15)+9:s[i]-48)*pow(16,j)+h(s,i-1,j+1):0;}
// Aufruf: printf("%i",h(a,strlen(a)-1,0));
Das dereferenzieren des Strings und der 3. Parameter brauchen zu viel Platz. Momentan fällt mir aber nicht ein, wie ich das umgehen könnte.
-
@interpreter
hmm rekursiv war diesmal bei mir auch schlechterint h(char*c){return*c?pow(16,strlen(c)-1)*(*c-48-7*(*c>57)&15)+h(c+1):0;}
liegt in diesem speziellen fall daran das man wissen muss wie lang das teil ist, an sonsten ists ja nur knapp länger
-
Windalf schrieb:
@interpreter
hmm rekursiv war diesmal bei mir auch schlechterint h(char*c){return*c?pow(16,strlen(c)-1)*(*c-48-7*(*c>57)&15)+h(c+1):0;}
liegt in diesem speziellen fall daran das man wissen muss wie lang das teil ist, an sonsten ists ja nur knapp länger
Ja. Bei solchen Funktionen kommen einem Wörter wie "return" und "strlen" endlos lang vor
Naja, dein Training mit deadbeef hat sich ausgezahlt
-
Naja, dein Training mit deadbeef hat sich ausgezahlt
beefywan hat mich viel gelehrt
Du musst halt noch einiges lernen junger Skywalker
-
Probe-Nutzer schrieb:
mir ist meistens klar, in welchem Forum ich mich befinde, auch dieses Mal war es so, mit hier war in meiner Antwort gemeint: in diesem Beitrags-Thread
Dann seh es doch einfach als Anreiz und zusätzliche Herausforderung, die Lektionen in dem Lehrbuch in aktuellem C umzusetzen. :p
-
@groovemaster2002 und Probenutzer
Immer wieder schön wenn man auch andere Leute trifft die dem Klugscheissen auch nicht abgeneigt sind
-
/* htoi: Hexadezimalzahlen in Dezimalzahlen umwandeln */ #include <stdio.h> /* Standard-Definitonsdatei */ #include <ctype.h> /* Bibliotheks-Datei */ #include <string.h> int htoi(char s[]); /* Funktion htoi liefert uns einen s-Wert, der den char-Tyü besitzt */ int pow(int base, int exp); /* Die Funktion pow */ int main() { char hex[11]; /* Der Variablen "hex" wird der Char-Typ zugewiesen und zudem noch eingeplant, dass diese Variable 11 Werte aufnehmen kann. Mehr als 11 Zeichen führen zum Absturz des Programms */ printf("\n-----Hex-->Dez-----\n\n"); /* Text am Anfang des Programms */ printf("Hex (0x...) : "); /* Nochmaliger Text neben der Eingabe der Hexadezimal-Zahl */ scanf("%s", hex); /* Der eingegebene Text wird bearbeitet mit "scanf" */ printf("Hex: %s ---> Dez: %d\n\n", hex, htoi(hex)); return 0; /* Wenn die Ausgabe gemacht wurde, wird der Wert 0 als Vollendung einer Umwandlung zurückgegeben */ } int htoi(char s[]) /* htoi gibt den Wert s zurück, weil dieser Wert der umgewandelte Wert ist, den man zu Anfang eingegeben hat */ { unsigned int dez = 0, i, j = 0; /* Die Variablen bekommen ihre Werte zugewiesen. "i" ist dabei eine Variable zum Hochzählen von "s", also dem eingegeben Text. "j" dient ebenso als Varibale zum Hochzählen und wird aber nur bei pow verwendet */ for (i=strlen(s)-1; i>1; i--) { if ( isdigit(s[i]) ) /* isdigit ist in diesem Falle ein Vergleich, denn isdigit ist diesem Quellcode ähnlich: s[i] >='0' && s[i] <= '9'. Im Klartext bedeutet dies, wenn eine Zahl zwischen 0 und 9 im eingegeben Text vorhanden ist, dann werden die nächsten Anweisungen ausgeführt */ { dez += (s[i] - '0') * pow(16,j); /* dez = dez + (s[i] - '0') ist die genaue Ausführung dieser Programmzeile. Die Umrechung der Dezimalzahl bildet sich wie folgt ab. Der vordere Teil der Rechnung ist klar, denn die Dezimal wird aus dem eingegeben Wert gebildet. Dazu kommt aber noch der Wert aus der Funktion "pow", der aus 16 Werten (0 - 9 und A - F) gebildet wird */ } if ( (s[i] >= 0x41 && s[i] <= 0x46) || (s[i] >= 0x61 && s[i] <= 0x66) ) {// a...f OR A...F // s[i]=tolower(*(s+i)); /* Der eingegebene Bereich wird in Kleinbuchstaben umgewandelt, wenn welche vorhanden sind */ dez += (s[i] - 'a' + 10) * pow(16,j); /* Die Dezimalzahl wird aus den ausgelesenen Werten von "s[i]" gebildet. */ } j++; /* "j" wird inkrementiert */ } return dez; /* Rückgabe der Dezimalzahl bzw. des Dezimalwertes */ } int pow(int base, int exp) /* Die Funktion rechnet die Hexadezimalzahlen um */ { int pow=1,i; /* Datentypvergabe und Wertevergabe */ for (i=0; i < exp; i++) /* Solange "i" nicht gleich null ist und i kleiner als der Exponent dann wird "i" reinitialisiert */ pow *= base; /* (pow = pow * base) */ return pow; /* Rückgabe des "pow-Wertes" */ }
Kann mir mal einer sagen, warum das Programm mir nicht den richtigen Hexadezimalwert errechnet ?"?
-
mal davon abgesehen das du es viel zu kompliziert machst...
for (i=strlen(s)-1; i>1; i--) { //die schleife ist falsch
muss is i>=0 laufen und wenn damit du keine endlosschleife draus machst dann kein unsigned verwenden...
an sonsten könnte du tolower auch gleich aufrufen was die sache dann einfacher macht und du auch kein vergleich mehr mit den grossbuchstaben brauchst...
an sonsten orientiere dich mal an den kurzlösungen von interpreter rackwitz und mir, die machen im wesentlichen auch nix anderers als du geschrieben hast halt nur auf wenig asciizeichen gekürzt...
int htoi(char s[]) /* htoi gibt den Wert s zurück, weil dieser Wert der umgewandelte Wert ist, den man zu Anfang eingegeben hat */ { unsigned int dez = 0, j = 0; /* Die Variablen bekommen ihre Werte zugewiesen. "i" ist dabei eine Variable zum Hochzählen von "s", also dem eingegeben Text. "j" dient ebenso als Varibale zum Hochzählen und wird aber nur bei pow verwendet */ int i; for (i=strlen(s)-1; i>=0;i--) { s[i]=tolower(s[i]); /* Der eingegebene Bereich wird in Kleinbuchstaben umgewandelt, wenn welche vorhanden sind */ if ( isdigit(s[i]) ) /* isdigit ist in diesem Falle ein Vergleich, denn isdigit ist diesem Quellcode ähnlich: s[i] >='0' && s[i] <= '9'. Im Klartext bedeutet dies, wenn eine Zahl zwischen 0 und 9 im eingegeben Text vorhanden ist, dann werden die nächsten Anweisungen ausgeführt */ { dez += (s[i] - '0') * pow(16,j); /* dez = dez + (s[i] - '0') ist die genaue Ausführung dieser Programmzeile. Die Umrechung der Dezimalzahl bildet sich wie folgt ab. Der vordere Teil der Rechnung ist klar, denn die Dezimal wird aus dem eingegeben Wert gebildet. Dazu kommt aber noch der Wert aus der Funktion "pow", der aus 16 Werten (0 - 9 und A - F) gebildet wird */ }else{ dez += (s[i] - 'a' + 10) * pow(16,j); /* Die Dezimalzahl wird aus den ausgelesenen Werten von "s[i]" gebildet. */ } j++; /* "j" wird inkrementiert */ } return dez; /* Rückgabe der Dezimalzahl bzw. des Dezimalwertes */ }