Forum: Mikrocontroller und Digitale Elektronik Probleme mit sscanf --> Hex


von Chris (Gast)


Lesenswert?

Hi ich hab gerade einen Hänger und komm nicht weiter.

Ich möchte über die Console den Benutzer am PC einen String eingeben 
lassen und daraus eine 16 bit Hex zahl generieren für die Einstellungen 
am µC.

Ich hab mir gedacht dabei einen String mit 4 chars abzufragen und daraus 
dann eine hex zahl zu machen.
Dabei hab ich gerade einen gedanklichen hänger und komme nicht weiter.
Wie erzeuge ich die Hex aus den Chars?
Hilfe mit Code-Bsp wäre super.

Danke.

von Karl H. (kbuchegg)


Lesenswert?

strtol

leider gibt es kein strtoi. Aber du bist ja hier nicht zeitkritisch.
Ansonsten: selber machen, ist nicht weiter schwer


* Funktion schreiben, die einen char '0'..'9','A'..'F' in den 
zugehörigen int umwandelt. Darauf aufbauend, dann eine Schleife, die das 
für alle 4 char hintereinander macht und zusmmanmontiert.
Getreu dem Motto:
 die (dezmalzahl) 12 ist auch nichts anderes als 1*10 + 2

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

1
char text[10] = "abcd";
2
uint16_t wert;
3
4
sscanf(text, "%x", &wert);

Du kannst und solltest allerdings auf sscanf verzichten, da das viel 
Programmcode erzeugt. Den numerischen Wert eines Hex-Digits ermittelst 
Du so:
1
uint16_t hexdigit(char c)
2
{
3
  if (c < '0')
4
  {
5
    // fehler!
6
  }
7
8
  if (c > '9')
9
  {
10
    if ((tolower(c) < 'a') || (tolower(c) > 'f'))
11
    {
12
      // fehler!
13
    }
14
  
15
    return (c - 'a' + 10) 
16
  }
17
  return (c - '0');
18
}


Das musst Du auf jede einzelne Stelle des eingegebenen Strings anwenden 
und das resultierende Nibble entsprechend in Dein Resultat einfügen:
1
char* text = "12db";
2
uint16_t wert;
3
4
wert = 0;
5
6
wert += hexdigit(text[3]);
7
wert += hexdigit(text[2]) << 4;
8
wert += hexdigit(text[1]) << 8;
9
wert += hexdigit(text[0]) << 12;

von Zack (Gast)


Lesenswert?

Ich würde es einen Tick eleganter formulieren

#define BASIS 16
#define STELLEN 4

char i;
int wert = 0;

for(i=0; i<STELLEN; i++) {
  wert *= BASIS;
  wert += hexdigit(text[i]);
}

Der Compiler weiß selber zu entscheiden, ob er mul oder shift verwendet, 
wenn als Basis 16, 10, 8, .... angenommen werden soll.
Ggf. noch für text[i] einen Pointer verwenden, der inkrementiert wird.

von Karl H. (kbuchegg)


Lesenswert?

Zack schrieb:
> Ich würde es einen Tick eleganter formulieren
>
> #define BASIS 16
> #define STELLEN 4
>
> char i;
> int wert = 0;
>
> for(i=0; i<STELLEN; i++) {
>   wert *= BASIS;
>   wert += hexdigit(text[i]);
> }
>
> Der Compiler weiß selber zu entscheiden, ob er mul oder shift verwendet,
> wenn als Basis 16, 10, 8, .... angenommen werden soll.
> Ggf. noch für text[i] einen Pointer verwenden, der inkrementiert wird.

Und nicht auf 4 Stellen bestehen.

Wenn der Benutzer F85 anstelle von 0F85 eingeben will, dann soll er das 
können, ohne das dies das Programm in Schwierigkeiten bringt.

von Zack (Gast)


Lesenswert?

>Wenn der Benutzer F85 anstelle von 0F85 eingeben will, dann soll er das
>können, ohne das dies das Programm in Schwierigkeiten bringt.

Na ja, soll denn nun auf Ende von text[] getestet werden oder wird text 
so formatiert, dass er immer 4 Stellen lang ist? :-)

Nehmen wir die erste Variante:


char i = 0;
int wert = 0;

while(text[i]) {
  wert *= BASIS;
  wert += hexdigit(text[i]);
  i++;
}

Jetzt fehlt uns aber noch die Fehlerbehandlung für ungültige Zeichen in 
hexdigit().

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.