Forum: Compiler & IDEs Datenkonvertierung


von Justus J. (jonas)


Lesenswert?

Moin,
wahrscheinlich ist mein Problem garnicht sehrgroß, aber ich sehe
einfach den Wald vor lauter Bäumen nicht mehr.

Ich bekomme von einem zuarbeitendem Programm einen String char
stream[100]; übergeben. In diesem String stehen nur hexadezimale Werte,
also in der Form wie "39AB38...." . Jetzt möchte ich diese aber
Byteweise weiterverarbeiten und zwar Bitweise, d.h. ich möchte die
ersten beiden Zeichen als 0x39 interpretieren und dann als Bits
"00111001" mit verschiedenen Routinen auswerten.

Krieg ich aber nicht hin, weil ich wohl nicht fit genug in C bin.
Wie krieg ich so eine konvertierung den wohl hin?

Justus

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Da ist nichts zu konvertieren.

von Mario Schrenk (Gast)


Lesenswert?

Versuch's mal mit

x = ((stream[i] - '0') << 4) | (stream[i+1] - '0');
i += 2;
...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Umm, ja, sorry, ich ziehe meine Bemerkung zurück. ;-)

von Peter D. (peda)


Lesenswert?

0 abziehen geht nicht bei Hex, aber sscanf geht:

sscanf( s, "%02x", &i);

Peter

von Mario Schrenk (Gast)


Lesenswert?

> 0 abziehen geht nicht bei Hex

Oh ja, stimmt. Und wenn dann noch Groß- und Kleinbuchstaben
berücksichtigt werden müssen, dann wird der Aufwand durch die nötigen
Fallunterscheidungen doch recht groß...

War also nichts mit einer einfachen, schnellen Codezeile.

von xXx (Gast)


Lesenswert?

-> Setzen, Sechs!!!

von Werner B. (Gast)


Lesenswert?

Mein Ansatz (ohne Gewähr)
1
#include <ctype.h>
2
3
void xxx(char* stream) {
4
 uint8_t result = 0;
5
 char* cp       = stream;
6
 uint16_t len   = strlen(stream);
7
8
 while(isxdigit(*cp)) {
9
  result <<= 4;
10
  if(*cp <= '9')
11
    result |= (*cp - '0');
12
  else 
13
    result |= ((*cp & ~' ') - 'A' + 10);
14
  cp++;
15
  len--;
16
  if(len & 1) == 0)
17
      machWasDamit(result);
18
 }
19
}

von Justus J. (jonas)


Lesenswert?

Danke für eure Antworten!

Ich hab es jetzt erstmal mit sscanf probiert, das funktioniert auf dem
Pc auch toll, aber wenn ich es auf dem Mikrocontroller einbinde, dann
funktioniert es garnicht mehr.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Ich hab es jetzt erstmal mit sscanf probiert, das funktioniert auf
> dem Pc auch toll, aber wenn ich es auf dem Mikrocontroller einbinde,
> dann funktioniert es garnicht mehr.

Sollte aber.  Was funktioniert denn genau nicht (und wie funktioniert
es nicht)?  Hast du Beispielcode?

von Justus J. (jonas)


Lesenswert?

Ok, ich hab das ganze mal so gelöst.



for(int c=0;c<=1;c++)
{
sscanf((id+(2*c)),"%02x", &shift);
for(int b=0;b<=7;b++)
{
  if (shift & 0x80)
     {
        if (c==0)
        gesamt1 = (gesamt1+bitwert[7-b]);
        if (c==1)
        gesamt2 = (gesamt2+bitwert[7-b]);
   }
    else ;
shift<<= 1;
}
}
gesamt = ((gesamt2 * 256)+gesamt1);
sprintf(gesamtchar,"%i",gesamt);
for(int b=0;b<=4;b++)
{
uart0_putchar(gesamtchar[b]);
}

von Karl H. (kbuchegg)


Lesenswert?

Was soll'n das sein?

Hast Du Dir schon mal den Wert von shift ausgeben lassen?
Du kannst Dir den ganzen Mambo-Zambo mit der ersten
b-Schleife komplett sparen.

Dezimal-Hex-Binaer sind nur andere Schreibweisen fuer
immer dasselbe: eine Zahl.
Und sscanf liefert dir diese Zahl.

von Karl H. (kbuchegg)


Lesenswert?

Im Übrigen gibt es da etwas, was Du Dir abgewöhnen solltest:

> for(int b=0;b<=4;b++)

Benutze kein <= in for Schleifen, es sei denn es gibt
einen extrem guten Grund dafuer.

  for( int b = 0; b < 5; b++ )

ist eine Schleife die 5 mal ausgeführt wird. D.h. die
Anzahl der Wiederholungen steht unmittelbar im Statement
ohne dass man gross rechnen oder analysieren muss.

  #define ANZAHL 28

  int irgendwas[ ANZAHL ];
        /* definiert ein Array mit 28 Eintraegen */

um dieses Array abzuarbeiten, schreibt man dann

  for( int i = 0; i < ANZAHL; i++ )
    ....

usw.
Das ist die übliche Art und Weise. Ein Programmierer checkt
mit seinem 'optischen Pattern-Matcher' (sprich Auge-Gehirn)
4 Dinge:
  * ist die Variable in allen 3 Ausdruecken immer diesselbe
      jawohl ist es: ist immer 'i'
  * steht da ein '<'
      yep. steht da
  * beginnt die Zaehlung mit 0
      yep.
  * kommt im letzten Ausdruck ein ++ vor und sonst nichts?
      yep.

-> Schlussfolgerung: Das ist eine Zaehlschleife, die i hochzaehlt.
Die Schleife wird ANZAHL mal (oder was halt im 2. Ausdruck rechts
vom '<' steht) wiederholt wird. Mehr analysiert er nicht sondern
beschaeftigt sich sofort damit, was in der Schleife passiert.
Erst wenn eine der 4 Dinge so nicht da stehen, dann beginnt
er darüber nachzudenken, warum denn die Schleife nicht in
ihrer Standardform geschrieben ist, was uns der Autor sagen
will und ob das überhaupt stimmen kann was da steht.

-> Standardform benutzen um anzuzeigen dass da nichts spezielles
passiert sondern es sich um eine stinknormale Standard-Zählschleife
handelt.

von Justus J. (jonas)


Lesenswert?

Danke für deine Tips, klingt ganz praktisch. Werde mehr auf die
Standardformen beim Programmieren achten.

Ansonsten funktioniert der Code aber.
Er macht aus 4 Hex-Werten die entsprechende Dezimalzahl.
Die wird dann in einen String geschrieben und über uart ausgegeben.

Werd mir das heute nochmal anschauen und ohne Schleife probieren.

von Karl H. (kbuchegg)


Lesenswert?

> Ansonsten funktioniert der Code aber.

Klar funktioniert er. Was Du machst ist: Du zerlegst
die Zahl in Bits und setzt dann aus den Bits wieder die
Zahl zusammen. D.h. das Ergebnis ist identisch mit dem
Ursprung. Damit ist aber der ganze Rechenweg dazwischen
umsonst und verbraucht nur Resourcen.

von Karl H. (kbuchegg)


Lesenswert?

> Er macht aus 4 Hex-Werten die entsprechende Dezimalzahl

Das wuerde

  long gesamt;
  sscanf( id, "%04lx", &gesamt );

auch machen :-)

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.