Probleme mit sscanf --> Hex

Gast #1877526
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.
#1877540
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
Persönliche Seite #1877548
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;
Gast #1877615
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.
#1877633
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.
Gast #1877679
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().

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren