Forum: PC-Programmierung hex in integer


von torsten (Gast)


Lesenswert?

Hallo.

Ich brauche eine Funktion um eine Konvertierung von Hex in Dec und 
umgekehrt durchzuführen.
Also genauer ein 2stelliges chararray in eine Intvariable und eben auch 
andersrum.
Gegoogelt habe ich natürlich auch schon und bin dabei auf die Funktionen 
itoa und atoi gestoßen.
Mit itoa funktionierts aber mit atoi leider nicht.
Außerdem habe ich noch xtoi und itox gefunden, aber anscheinend muss man 
sich die selber schreiben?

Was kann ich denn nun benutzen und wie?

Freundliche grüße, torsten

von chick (Gast)


Lesenswert?

Ich hoffe mal für Dich, das Projekt scheitert nicht am Fehlen der 
simplen Wandlung der Zahlen.

In der Zeit, in der Du im Netz gesucht hast, hättest Du die Funktion 
locker geschrieben und getestet. Vorausgesetzt, Du willst was 
schreiben...

von Max W. (max96)


Lesenswert?

Du willst also aus einer Zahl als cstring einen int machen? Dafür gibt 
es wie du schon sagtst atoi(es funktioniert warscheinlich bei dir nicht 
weil du eine referenz auf dein char array übergeben musst und nicht das 
char array).
Als Beispiel:
1
char Zahl[3] = {'1','2','\0'};
2
int ZahlAlsInt = atoi(&Zahl);

von Noname (Gast)


Lesenswert?

>(es funktioniert warscheinlich bei dir nicht
weil du eine referenz auf dein char array übergeben musst und nicht das
char array).

Was in C ein und das selbe ist. ;-)

von torsten (Gast)


Lesenswert?

Danke schonmal, war zum einen ein Verständigungsproblem.
Ich dachte das itoa die "umkehrfunktion" von atoi ist.
Mit itoa bekommt man ja einen hexadezimalen Wert.
Aber anscheinend kann man das mit atoi nicht umkehren.

Mit der Adresse übergeben wäre nicht das Problem, ich dachte nur 
einfach, dass ich atoi einfach einen hexadezimal wert geben kann und 
daraus ein int wert, mehr wollte ich nicht. Wie bewerkstellge ich nun 
das?

Danke, torsten

von Max W. (max96)


Lesenswert?

Stimmt hab es gerade getestet :D Aber woran soll es dann liegen. Wie 
sieht denn der Fehler genau aus?

von torsten (Gast)


Lesenswert?

wenn ich atoi das array übergebe in dem eine 2stellige hexZahl ist, 
kommt 0 raus. Scheint so als wäre atoi nicht geeignet, um hex in int 
umzuwandeln?
Aber genau das wollte ich ja :(

von Max W. (max96)


Lesenswert?

Dem Compiler bzw. deinem PC ist es egal ob die Zahl in Hex oder in 
Decimalschreibweise eingegeben wird für ihn werden alle Zahlen Binär 
dargestellt.
1
int Hexwert = 0xFF;
2
printf("%d", Hexwert); //Ausgabe ist 255
 Kannst du mal deinen Code posten?

von DirkB (Gast)


Lesenswert?

Wie sieht deine Hexzahl aus? Hat sie den 0x Präfix?

Oder kannst du bei deiner atoi die Basis mit angeben?

Besser du nimmst strtol.

von torsten (Gast)


Lesenswert?

So einfach :o

Eigentlich wollte ich ja ne Funktion, um die auch mit nem AVR 
anzuwenden, für Computerprogramme ok, aber für nen Controller?

von torsten (Gast)


Lesenswert?

ok, schade mal wieder schlechtes timing, ich probiers mal...

von Max W. (max96)


Lesenswert?

Wo kommt denn dein Hex Array her? Vielleicht gibt es ja einen 
einfacheren Weg. EDIT: Das geht auch auf jedem uC.

von torsten (Gast)


Lesenswert?

1
int adress;
2
3
char buffer[] = {'f', 'f'}; // beispielhaft für eine empfangene Adresse
4
5
*fehlender Code*   // die als hexadezimaldargestellte Zahl soll in adress als ganzzahl gespeichert werden

Das soll gemacht werden, ich habe mich an den funktionen etwas 
aufgehängt :D

von Max W. (max96)


Lesenswert?


von torsten (Gast)


Lesenswert?

Also zusätzlich:

Die UART vom Controller empfängt eine Adresse z.B. "0d".
Diese soll nun nicht als hex sondern als dezimalzahl in einen int.

Das Problem tritt nicht so selten auf, aber trotzdem weiß ich nicht wie 
ich das umwandeln soll :(

von torsten (Gast)


Lesenswert?

das mittlere ist ja nun am einfachsten, aber wie soll das denn mit nem 
Controller gehen?

von Max W. (max96)


Lesenswert?

Das ist ne standart C Funktion also einfach Header includen und loslegen 
könnte nur viel Flash Speicher kosten.

von DirkB (Gast)


Lesenswert?

Da ist strtol das einfachste. sscanf ist viel zu teuer (Speicher, 
Laufzeit)

Allerdings erwarten alle diese Funktionen einen Null-terminierten 
String. Wie es in C üblich ist.
1
char buffer[] = {'f', 'f', '\0'}; 
2
int zahl;
3
zahl = strtol(buffer, NULL, 16);

von torsten (Gast)


Lesenswert?

OK, vielen Dank.

Strtol hatte mich wegen des, wieso eigentlich long int, gestört.

Im Nachhinein kommt mir printf auch furchtbar undynamisch vor.

Vielen Dank :D

von DirkB (Gast)


Lesenswert?

torsten schrieb:
> wieso eigentlich long int, gestört.

Weil ein int in ein long passt.
Und warum sollte man dann zwei Funktionen schreiben?
Und noch eine für short und char. :-)

Wieso denn jetzt noch printf?

von Uwe (Gast)


Lesenswert?

Ich denke es wird von dir verlangt dies ohne library Funktionen zu 
lösen.
Überprüfe ob das erste char im bereich 0x30 bis 0x39 liegt (also ASCII 
von 0-9). Wenn nicht könnte es sein das es im Bereich A-F liegt. Und das 
wäre welcher ASCII Wert ? Tipp schau mal in eine ASCII Tabelle.

Wenn du dies getan hast kannst du falls es im Bereich von 0x30-0x39 
liegt einfach 0x30 subtrahieren und um 4 Bit nach Links schieben.

Was machst du nun mit dem nächsten char ?

Wieso habe ich um 4 Bit nach links geschoben ?

Wieviele einzelne Ziffern ergeben 1 Byte in Hexadezimal ?

von Uwe (Gast)


Lesenswert?

Was tust du wenn es nicht im Bereich 0x30-0x39 liegt ?

von Karl H. (kbuchegg)


Lesenswert?

Uwe schrieb:
> Ich denke es wird von dir verlangt dies ohne library Funktionen zu
> lösen.
> Überprüfe ob das erste char im bereich 0x30 bis 0x39 liegt (also ASCII
> von 0-9). Wenn nicht könnte es sein das es im Bereich A-F liegt. Und das
> wäre welcher ASCII Wert ? Tipp schau mal in eine ASCII Tabelle.

Zur Übung ist der Tip nicht so schlecht.
Für die Programmierung ist das aber ein schlechter Tip. Kein Mensch muss 
die ASCII Codes auswendig können. Die kennt der Compiler nämlich auch 
und anstelle von 0x30 kannst du ruhig auch '0' hinschreiben. Dann
* sieht jeder, dass es hier um das Zeichen '0' geht
* muss keiner ASCII Tabellen wälzen um zu sehen, dass 0x30 für das
  Zeichen '0' steht.

Auch wenn es überrasschend sein mag: In C kann, darf und soll man mit 
Charactern Arithmetik betreiben (*)

   Wert = Zeichen - '0';

ist völlig legal und gleichwertig zu

   Wert = Zeichen - 0x30;

Nur eben mit dem Unterschied, das in der ersten Version ziemlich klar 
ist, was die Absicht war.

  if( Zeichen >= '0' && Zeichen <= '9' )

ist dann doch ein wenig leichter zu verstehen, als

  if( Zeichen >= 0x30 && Zeichen <= 0x39 )


(*) Das ist: solange man sich im 7-Bit Ur-ASCII Raum bewegt. Erst wenn 
das MSB eines Zeichens gesetzt ist (Sonderzeichen wie Umlaute) wird es 
unter Umständen spannend ob der Compiler einen char nun signed oder 
unsigned auffasst. Dann ist man mit der Hex-Schreibweise unter Umständen 
besser bedient.

von Uwe (Gast)


Lesenswert?

Wenn einem erst einmal bewußt ist, daß die ASCII Zahlen hintereinander 
in der Tabelle stehen dann versteht man auch den Sinn. Genauso wie die 
Buchstaben a-z bzw. A-Z. War nur als Denkanstoß für torsten gedacht.
Noch was torsten :
1. Wieviele ASCII Zeichen werden denn benötigt um eine 32Bit Integer 
vollständig zu beschreiben ?
2. Wieviel Bytes werden denn benötigt um eine 32Bit Integer vollständig 
zu beschreiben ?

von Karl H. (kbuchegg)


Lesenswert?

Uwe schrieb:
> Wenn einem erst einmal bewußt ist, daß die ASCII Zahlen hintereinander
> in der Tabelle stehen dann versteht man auch den Sinn.

Drum sag ich ja:
Als Tip, als Denkanstoss: nicht schlecht.
Aber für die Programmierung nicht notwendig.


Leider sieht man das allzuoft
   if( c == 0x3A )    // war das Zeichen ein :

schreib doch gleich im Code hin was du meinst
   if( c == ':' )

es gibt keinen Grund es nicht zu tun.

Sowas sollte man sich von Anfang an gleich gar nicht eingewöhnen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.