Umwandeln von Char "C" und "2" in Hex C2

Gast #4311445
Lesenswert?
• ▲
▼
Hallo zusammen,

ich schreibe gerade an einer UART Kommunikation, bei der Eigentliche 
Hex-Bytes also z.B 0xC2 als 2 einzelne Char (je ein byte) C und 2 
übermittelt werden.

Einseitig habe ich die Umwandlung mit Bitmanipulation und einem 
Hilfsarray hinbekommen, jedoch klappt der folgende Weg nicht.

Es liegt C als Char vor, also 0x43 und somit 0100 0011
ebenso wie 2 also 0x32 und somit 0011 0010

Nun möchte ich diese beiden Chars wieder zu einem Hexwert zusammenfügen.

Leidet kommt bei meinem Veruschen alles raus, aber nicht dass was ich 
möchte, nämlich 0xC2, also 1100 0010

Kann mir vielleicht jemand auf die Sprünge helfen.
Bin mir fast sicher, dass ich nur einen Denkfehler hab.

Besten Dank.

Gruß Tobias
#4311450
Lesenswert?
• ▲
▼
Aus einem Char, welches eine Zahl ist, einen Int zu machen ist ja kein 
Ding, weißt du, oder? Tipp: ATOI.
Und aus dem Char C eine Zahl zu machen ist ja auch kein Ding, könnte man 
über eine Switch-Case-Funktion lesen, es sind ja nur 6 Werte, die bei 
rum kommen können.
Gast #4311452
Lesenswert?
• ▲
▼
Tobias S. schrieb:

> Bin mir fast sicher, dass ich nur einen Denkfehler hab.

Ich würde eher sagen: du beherrschst einfach nicht mal ansatzweise die 
Sprache, in der du programmierst...

Das hat nix mit "Denken" zu tun. Ist vielmehr eine reine Fleißaufgabe. 
So ähnlich wie das Auswendiglernen von Gedichten. Jedenfalls nicht sehr 
viel darüber.
Gast #4311460
Lesenswert?
• ▲
▼
c-hater schrieb:
> Tobias S. schrieb:
>
>> Bin mir fast sicher, dass ich nur einen Denkfehler hab.
>
> Ich würde eher sagen: du beherrschst einfach nicht mal ansatzweise die
> Sprache, in der du programmierst...
>
> Das hat nix mit "Denken" zu tun. Ist vielmehr eine reine Fleißaufgabe.
> So ähnlich wie das Auswendiglernen von Gedichten. Jedenfalls nicht sehr
> viel darüber.

Diesen Schwätzer einfach nicht beachten. Der kann nichts, der macht sich 
nur wichtig.
Gast #4311461
Lesenswert?
• ▲
▼
Michael K. schrieb:
> Aus einem Char, welches eine Zahl ist, einen Int zu machen ist ja
> kein
> Ding, weißt du, oder? Tipp: ATOI.
> Und aus dem Char C eine Zahl zu machen ist ja auch kein Ding, könnte man
> über eine Switch-Case-Funktion lesen, es sind ja nur 6 Werte, die bei
> rum kommen können.

Hallo Michael,

ja das ist korrekt.
Nur fuchst es mich etwas, dass ich es nicht mit Bitmanipulation 
hinbekommen.
Im Endeffekt ist es ja nur ein zusammenführen von 2 nibble.

Nur genau beim verschieben und Ver"UND"en ist wahrscheinlich mein 
Fehler.

Gruß Tobias
Gast #4311462
Lesenswert?
• ▲
▼
Juven schrieb:
> c-hater schrieb:
>> Tobias S. schrieb:
>>
>>> Bin mir fast sicher, dass ich nur einen Denkfehler hab.
>>
>> Ich würde eher sagen: du beherrschst einfach nicht mal ansatzweise die
>> Sprache, in der du programmierst...
>>
>> Das hat nix mit "Denken" zu tun. Ist vielmehr eine reine Fleißaufgabe.
>> So ähnlich wie das Auswendiglernen von Gedichten. Jedenfalls nicht sehr
>> viel darüber.
>
> Diesen Schwätzer einfach nicht beachten. Der kann nichts, der macht sich
> nur wichtig.

Das hab ich bemerkt, ich ignoriere das jetzt einfach dezent
#4311469
Lesenswert?
• ▲
▼
Hallo,

was ist das Problem?
Die 2 Char als 8-Bit Wert betrachten. Ist der Wert größer als 9 (0x39) 
dann - 0x37, wenn nicht -0x30.
Den höherwertigen teil * 16 oder 4 Bit nach links schieben.
Den niederwertigen Teil genauso behandeln und mit den oberen ver-odern.

Macht man beim konvertiren von Bin nach Hex genauso, nur andersrum.

Gruß aus Berlin
Michael
#4311470
Lesenswert?
• ▲
▼
Tobias S. schrieb:

> Kann mir vielleicht jemand auf die Sprünge helfen.

Fang damit an, dir eine Funktion zu schreiben, die aus EINEM Character 
den entsprechenden Zahlenwert generiert.
Das ist an für sich leicht. Denn wenn dieses Zeichen im Bereich '0' bis 
'9' liegt, dann brauchst du vom ASCII Code des Zeichens nur den ASCII 
COde von '0' abziehen und du hast den numerischen Wert. Liegt das 
Zeichen aber im Bereich 'A' bis 'F', dann ziehst du von ihm den ASCII 
COde von 'A' ab und addierst wieder 10. Dann das Hexadezimale Digit A 
hat ja den dezimalen Wert 10.
1
uint8_t toHexDigit( char c )
2
{
3
  if( c >= '0' && c <= '9' )
4
    return c - '0';
5

6
  if( c >= 'A' && c <= 'F' )
7
    return c - 'A' + 10;
8

9
  return 0;

AUf die Kleinbuchstaben nicht vergessen! Das ist aber als Übung für den 
geneigten Leser gedacht.

Um aus 2 eingehenden Zeichen die enstprechende Zahl zu machen ist dann 
einfach
1
uint8_t zahl = toHexDigi( erstes_Zeichen ) * 16 + toHexDigit( zweites_Zeichen );

> Bin mir fast sicher, dass ich nur einen Denkfehler hab.

es wäre gut, wenn du COde zeigen würdest. Dann könnte man dir zeigen, wo 
du den Denkfehler hast.
#4311481
Lesenswert?
• ▲
▼
Tobias S. schrieb:

> Nur genau beim verschieben und Ver"UND"en ist wahrscheinlich mein
> Fehler.

Überlass solchen Kleinscheiss dem Compiler. der kann das.

Für dich ist es ganz einfach:
Um aus den beiden dezimalen Ziffern 3 und 4 die Zahl 34 zu erzeugen, 
rechnest du
1
   3 * 10     -> 30
2
                + 4
3
              ------
4
                 34

und nichts anderes machst du bei Hex-Ziffern. Nur dass du anstelle von 
10 mit 16 multiplizierst. Denn genau deswegen ist es ja das 
Hexadezimalsystem.
Gast #4311487
Lesenswert?
• ▲
▼
Karl H. schrieb:
> Tobias S. schrieb:
>
>> Kann mir vielleicht jemand auf die Sprünge helfen.
>
> Fang damit an, dir eine Funktion zu schreiben, die aus EINEM Character
> den entsprechenden Zahlenwert generiert.
> Das ist an für sich leicht. Denn wenn dieses Zeichen im Bereich '0' bis
> '9' liegt, dann brauchst du vom ASCII Code des Zeichens nur den ASCII
> COde von '0' abziehen und du hast den numerischen Wert. Liegt das
> Zeichen aber im Bereich 'A' bis 'F', dann ziehst du von ihm den ASCII
> COde von 'A' ab und addierst wieder 10. Dann das Hexadezimale Digit A
> hat ja den dezimalen Wert 10.
> uint8_t toHexDigit( char c )
> {
>   if( c >= '0' && c <= '9' )
>     return c - '0';
>
>   if( c >= 'A' && c <= 'F' )
>     return c - 'A' + 10;
>
>   return 0;
>
> AUf die Kleinbuchstaben nicht vergessen! Das ist aber als Übung für den
> geneigten Leser gedacht.
>
> Um aus 2 eingehenden Zeichen die enstprechende Zahl zu machen ist dann
> einfachuint8_t zahl = toHexDigi( erstes_Zeichen ) * 16 + toHexDigit(
> zweites_Zeichen );
>
>> Bin mir fast sicher, dass ich nur einen Denkfehler hab.
>
> es wäre gut, wenn du COde zeigen würdest. Dann könnte man dir zeigen, wo
> du den Denkfehler hast.

Vielen Dank,

du wirst lachen, oder mir es nicht glauben, aber genau den Ansatz habe 
ich jetzt gerade aufgeschrieben.

Das macht mich jetzt aus eigenem Interesse nicht ganz glücklich aber es 
klappt auf jeden Fall..


Also vielen Dank, für eure Hilfe :)

Gruß Tobias
#4311540
Lesenswert?
• ▲
▼
#include <stdio.h>

unsigned char asc2char(unsigned char ziffhi, unsigned char zifflo)
{
  unsigned char ziff2nibble(unsigned char ziff)
  {
    if (ziff < ':') { return ziff - 48; }
    if (ziff < 'G') { return ziff - 55; }
    return (ziff - 87);
  }

 return (ziff2nibble(ziffhi) << 4) + ziff2nibble(zifflo);
}

int main(void)
{
  unsigned char by;

  by= asc2char('f','3');
  printf("\n\r%.2X\n\r",by);
  return 0;
}
#4311693
Lesenswert?
• ▲
▼
... dann ... muesste ich auch schreiben:

return ziff - 'A' + 10;

Hmm, ich komme noch von "richtig alten Zeiten" als ein Compiler noch 
nicht so "schlau" war und ein -'A' + 10 intern NICHT optimierte und 
daraus noch eine Rechenoperation mehr machte...

(smile ... die "Entry-Punkte" für '0', 'a', 'A' des Ascii-Codes sind mir 
damals ins Blut gelegt worden)


Der Uralte Compiler war damals ein Compiler fuer einen 8048 MCU auf 
einem HP-150 Rechner mit C/PM 86

Sorry (werde mich bei weiteren Codeschnippseln "bessern")

Ralph

PS: ich weiß nicht mehr welcher C- Compiler das war .... irgendwie muß 
das um das Jahr 1981 gewesen sein (da war ich mit der Lehre gerade 
fertig)
#4311705
Lesenswert?
• ▲
▼
Ralph S. schrieb:
> ... dann ... muesste ich auch schreiben:
>
> return ziff - 'A' + 10;

Ja. Klar.
so ist es doch viel einfacher zu verstehen, was hier die Absicht ist.

> Hmm, ich komme noch von "richtig alten Zeiten" als ein Compiler noch
> nicht so "schlau" war und ein -'A' + 10 intern NICHT optimierte und
> daraus noch eine Rechenoperation mehr machte...

Ah geh.
Schon die ersten Compiler vor Beginn der Zeitrechnung konnten Constant 
Folding. Das ist die simpelste aller Übungen für einen Compiler. Einen 
Expression Tree muss er sich sowieso aufbauen, um notwendige Casts 
einzubauen. Diesen Baum dann noch einmal rekursiv abklappern, bei jeden 
Operations-Knoten links im Baum nachsehen, ob da eine Konstante steht, 
rechts nachsehen ob eine Konstante steht und wenn ja den 
Operationsknoten samt linken und rechtem Subknoten durch das 
ausgerechnete Ergebnis zu ersetzen, ist trivial.
Wenn ein Compiler das nicht kann, dann nur aus stinkender Faulheit des 
Compilerbauers. Technisch sind zumindest die einfacheren Formen von 
Constant Folding bei dem die Konstanten direkt hintereinander kommen ein 
Kinderspiel.
#4312013
Lesenswert?
• ▲
▼
>AUf die Kleinbuchstaben nicht vergessen! Das ist aber als Übung für den
>geneigten Leser gedacht.

evtl. solltem an noch abfangen das ein böser Bube auch mal:
Q§ W° R+ T" Z* Uç I% O& P/ ü( l) K= j? S` ~^ '...
oder ein paar Steuerzeichen senden könnte.

hat mit der gestellten Frage nichts mehr zu tun aber die ist ja auch 
beantwortet
hauspapa
#4312024
Lesenswert?
• ▲
▼
Der Vollständigkeit halber:
Kleine Erweiterung, damit Karls Funktion auch mit Kleinbuchstaben als 
Hexziffern umgehen kann:

1
uint8_t toHexDigit( char c )
2
{
3
  if( c >= '0' && c <= '9' )
4
    return c - '0';
5

6
  if( c >= 'A' && c <= 'F' )
7
    return c - 'A' + 10;
8

9
  if( c >= 'a' && c <= 'f' )
10
    return c - 'a' + 10;
11

12
  return 0;
13
}


Gruß, Stefan

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.