mikrocontroller.net

Forum: PC-Programmierung C String in Hexstring umwandeln


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo gibt es eine Mödlickeit in C einen String in einen Hexstring 
umwandeln.

BSP.(Hexwerte stimmen natürlich nicht)

char x[]="Ha"

char b[]= "04 F8"

etwas so,

dank im Voraus

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Natürlich gibt es die Möglichkeit. Du schreibst Dir eine entsprechende 
Funtion, und schon geht's.

Du musst ja nur den String zeichenweise iterieren, jedes Zeichen in eine 
zweistellige Hexzahl umwandeln, ein Leerzeichen dazwischen packen und 
das Resultat in den Ergebnispuffer packen.

Leichte Übung.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
na ich hab auch ne vorstellung wie man das eventuell machen könnte.
ich hab mir zwei variablen abgelegt lowbyte,highbyte,
dann hab ich ne for schleige wo ich für jedes Zeichen des Strings den 
dec wert bestimme
in der for schleife ab ich ne switch anweisung
und dann hab ich das  256 cases
wo ich dann, wenn dec zum bsp 1 ist lowbyte 0 und highbyte 1

und zum schluss setze ich dann meinen neuen string zusammen
aber das muss doch auch einfacher gehen, falls das so überhaupt geht
mein Weg gefällt mir überhaupt nicht

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> dann hab ich das  256 cases
ja das geht dann auch einfacher - ein computer kann auch rechnen. 
Übelegt dir mal eine formel

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du könntest Dir mal die Funktion itoa in der Dokumentation Deines 
C-Compilers ansehen.

Autor: Wegstaben Verbuchsler (wegstabenverbuchsler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lownibble = byte & 0x0f;
highnibble = (byte & 0xf0) >> 4;

if(0..9): lownibble += '0';
if(10..15): lownibble += 'a'-10;

so in der Art :-)


VG,
/th.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich probiere es jetzt über modulo
hab zuerst char array angelegt, char a{0,1,2,.....,E,F}
char highbyte
char lowbyte


hab jedes Zeichen durch 16 gerechnet, da bekomme ich ja einen Integer 
zurüch, der mir die hexzahl beschreibt.

und dann hab ich ne if-Anweisung

Integer<127

highbyte 0;

lowbyte=tab[a]



aber irgendwie funktionierts noch nicht so ganz

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann zeig doch mal den kompletten quellcode.

Wenn du die dann noch die ASCII Tabelle anschaust, den bereich von 
'0'-'F' wirst du auch noch merken das du das array nicht wirkich 
brauchst.

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man könnte sich natürlich auch einmal die Standardfunktion sprintf() 
genauer ansehen.

Gruß, DetlevT

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gast schrieb:

> hab jedes Zeichen durch 16 gerechnet, da bekomme ich ja einen Integer
> zurüch, der mir die hexzahl beschreibt.
>
> und dann hab ich ne if-Anweisung
>
> Integer<127
>
> highbyte 0;
>
> lowbyte=tab[a]

Sehr brav. Damit bist du dann auch für EBCID gerüstet. Damit 
programmierst du exakt am C-Standard und dem was er dir alles erlaubt.

(Zurücklehn und auf das Geheul wartend)

> aber irgendwie funktionierts noch nicht so ganz

Grundregel:
Beschreibe nicht deinen Code. Zeig ihn einfach her.

Autor: asffrsff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
char Wort[] = "Hallo";
   char HexWort[100];

   for(int i=0; i < sizeof(Wort); ++i)
   {
      sprintf(&HexWort[i*5], "0x%02X ", Wort[i]);
   }

   for(int i=0; i < sizeof(Wort)*5; ++i)
   {
      printf("%c", HexWort[i]);
   }

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ asffrsff
spielverderber, damit lernt er doch nichts.

und warum 2 Schleifen, das ganze dann noch mit printf ist auch nicht 
gerade performant.
Der Gast war doch schon auf dem richtigen weg.

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
    char Wort[] = "Hallo";
    char HexWort[100];
    char *pHexWort, *pWort;
    
    pHexWort = HexWort;
    pWort    = Wort;

    while(*pWort)
    {
       pHexWort += sprintf(pHexWort, "0x%02X ", *pWort++);
    }

    pHexWort = '\0';
    printf("%s", HexWort);


**grins**
ein paar Sachen korrigiert usw., ...

Ansonsten:
sizeof(array) liefert die Grösse des Arrays zurück,
strlen(array) liefert die Länge des Strings im Array zurück. Das hab ich 
im while(...) verhackstückt.

VG,
/th.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Random ...
Hoffentlich wird "Hallo" nicht mal länger als 20 Zeichen ...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
  pHexWort += sprintf(pHexWort, "0x%02X ", *pWort++);

Hi, hi.
Das ist wirklich eine schöne, trickreiche Lösung. Gefällt mir :-)

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> @Random ...
> Hoffentlich wird "Hallo" nicht mal länger als 20 Zeichen ...

Nunja, ist ja nur ein sample :-)
Latürnich muss man sich da vorher Gedanken drüber machen.

Aber, ich kann dich beruhigen, solange wir ASCII verwenden wird "Hallo" 
immer 5+1 Zeichen lang sein **grins**

VG,
/th.

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber wenn dir schon mal dabei sind....
    char *Wort = "Hallo";
    char *HexWort;
    char *pHexWort, *pWort;
    
    HexWort = (char *) malloc ((strlen(Wort)* 5 * sizeof(char)) +1);
    pHexWort = HexWort;
    pWort    = Wort;

    while(*pWort)
    {
       pHexWort += sprintf(pHexWort, "0x%02X ", *pWort++);
    }

    pHexWort = '\0';
    printf("%s", HexWort);


Über die Namen lässt sich noch streiten...
Man beachte, nun ist kein Array mehr drin. Damit ist nun auch 'Wort' ein 
schöner(er) String.
Btw: Ich liieeeebe Zeiger **grins**

VG,
/th.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
immer diese magic numbers..
> HexWort = (char *) malloc ((strlen(Wort)* 5 * sizeof(char)) +1);

jetzt noch das langsame printf rausschmeissen und dann ist es auch noch 
schnell...

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh aufgebstellung verfehlt.

6. Setzen

Threaderstellen wollte

> char b[]= "04 F8"

als ausgabe. Nichts mit 0x..

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Random ... schrieb:

> Man beachte, nun ist kein Array mehr drin. Damit ist nun auch 'Wort' ein
> schöner(er) String.

Nur noch eine winzig kleine Unschönheit :-)
Der erzeugte String endet mit einem ' '

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naguhhht:
    #define FORMAT   "0x%02x "

    char *Wort = "Hallo";
    char *HexWort;
    char *pHexWort, *pWort;
    
    HexWort = (char *) malloc ((strlen(Wort) * sizeof(FORMAT) * sizeof(char)) +1);
    pHexWort = HexWort;
    pWort    = Wort;

    while(*pWort)
    {
       pHexWort += sprintf(pHexWort, FORMAT, *pWort++);
    }

    --pHexWort = '\0';
    pHexWort = HexWort;

    while(*pHexWort) fputc(*pHexWort++, stdout);

Aber ich glaube, nun ists ein wenig oversized gegenüber dem, was der 
Topic Schreiber mal wollte **grins**

Anm.: Hier funzt das sizeof mal :-)


VG,
/th.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
  ...
   * sizeof(FORMAT)
  ...

Hmm. Jetzt bist du übers Ziel hinausgeschossen.
Das was du da vorhast, ist gar nicht so einfach wasserdicht zu machen.

sizeof(Format) ergibt in diesem speziellen Fall 8



   --pHexWort = '\0';

Probier das mal mit
    char *Wort = "";

aus :-)

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, machen wir strlen(FORMAT).
Hatte das hier kurz getestet und das Ergebnis war 6. Damit dachte ich, 
das wär ok.
Aber so kann man sich irren :-)

VG,
/th.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja danke, wusste nicht das es eine direkte Funktion (sprintf) gibt.

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Probier das mal mit
>    char *Wort = "";

Hier gehts, weil wir ja mit dem Pointer schon einen hinterm letzten 
(Leer-)Zeichen stehen.
Klar, dass man das nciht zu Beginn machen darf :-)
#define FORMAT   "0x%02x "

    char *Wort = "Hallo";
    char *HexWort;
    char *pHexWort, *pWort;
    
    HexWort = (char *) malloc ((strlen(Wort) * sizeof(FORMAT) * sizeof(char)) +1);
    pHexWort = HexWort;
    pWort    = Wort;

    while(*pWort)
    {
       pHexWort += sprintf(pHexWort, FORMAT, *pWort++);
    }

    if(pHexWort> HexWort) *(--pHexWort) = '\0';
    else *pHexWort = '\0';

    pHexWort = HexWort;

    while(*pHexWort) fputc(*pHexWort++, stdout);


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Random ... schrieb:
> ok, machen wir strlen(FORMAT).

Auch das funktioniert nicht.

Das Problem: Der Inhalt von FORMAT codiert wieviele chars du pro 
Einheit benötigst. Du bräuchtest so etwas wie einen Parser, der sich den 
Formatstring vornimmt und ausrechnet, wieviele Character printf dafür 
erzeugen wird.

"0x02X " produziert 5 Stellen
"0x04X " produziert 7 Stellen

Und selbst das wird nicht stimmen, da printf auch die angegebenen Zahlen 
ignorieren kann, wenn das Feld zu klein ist um das Ergebnis aufzunehmen.

Machst du

   printf( "%2d", 128 );

ist das Ergebnis 3 Character lang, auch wenn im Formatstring steht, dass 
du nur 2 Character haben willst.

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry, stimmt, hatte sizeof("Hallo") dummerweise ausprobiert. Mein 
Gedankenfehler, da ich ja noch an was anderem arbeite **g**

    #define FORMAT         "0x%02x "
    #define HEX_NUM_CHARS  5

    char *Wort = "Hallo";
    char *HexWort;
    char *pHexWort, *pWort;
    
    HexWort = (char *) malloc ((strlen(Wort) * HEX_NUM_CHARS * sizeof(char)) +1);
    pHexWort = HexWort;
    pWort    = Wort;

    while(*pWort)
    {
       pHexWort += sprintf(pHexWort, FORMAT, *pWort++);
    }

    if(pHexWort> HexWort) *(--pHexWort) = '\0';
    else *pHexWort = '\0';

    pHexWort = HexWort;

    while(*pHexWort) fputc(*pHexWort++, stdout);


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Random ... schrieb:
>>Probier das mal mit
>>    char *Wort = "";
>
> Hier gehts, weil wir ja mit dem Pointer schon einen hinterm letzten
> (Leer-)Zeichen stehen.
> Klar, dass man das nciht zu Beginn machen darf :-)

:-)
Das einfachste an dieser Stelle wird wohl ein vorzeitiger return sein 
(Ich geh mal davon aus, dass der ganze Klapperatismus sinnvollerweise in 
einer Funktion stattfinden wird)

Was soll man auch bei einem leeren Eingabestring für einen Hex-String 
erzeugen :-)

Ich wollte nur aufzeigen, dass der Teufel oft im Detail steckt.
Es ist nämlich erstaunlich schwierig, solche 
String-wird-aus-anderem-String-generiert Funktion zu schreiben, die 
absolut wasserdicht sind.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> da ich ja noch an was anderem arbeite **g**

Da gehts dir wie mir.  ggggg

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jepp, haste recht.
So was testet man aber idR. beim Funktionseintritt.

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
>> da ich ja noch an was anderem arbeite **g**
>
> Da gehts dir wie mir.  ggggg

aber immer wieder nett so ne spielerei. Schön wirds dann bei **array :-)

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, hab einen eurer Codes mal ausprobiert und etwas herumgespielt. 
Mir ist irgendwie unklar warum nicht der String HexWort richtig 
ausgegeben wird wenn ich ihn in einer Funktion zurückgebe, ich versuche 
grad C zu lernen.


#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

char* test(void);



int main(int argc, char *argv[])
{

char *d;
 d=test();
 printf("%s\n", d);


system("PAUSE");
  return 0;
}



char* test(void)
{
      int b=5;
     char Wort[] = "Hallo";
      char co[100];
      char HexWort[100];
      int i=0;
      for( i=0; i < b; ++i)
   {
      sprintf(&HexWort[i*3], "%02X ", Wort[i]);
   }

   //printf("%s", HexWort);
    for(i=0; i < sizeof(Wort)*5; ++i)
     {
      //printf("%c", HexWort[i]);
     }

   strcpy(co,HexWort);
   //printf("\n%s\n", co);
   return co  ;
}

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
co ist eine lokal variabel in der Funktion, sie existiert nicht mehr 
wenn die funktion beenden ist.

> system("PAUSE");
bitte mach soetwas nicht, das ist ja furchtbar.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also müsste ich ein zeiger der auf die adresse von co zeigt zurückgeben 
oder was könnte man da machen

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> also müsste ich ein zeiger der auf die adresse von co zeigt zurückgeben

Nein, das tust Du ja schon.
Vielmehr muss die Variable außerhalb der Funktion definiert/deklariert 
und ihr als Zeiger übergeben werden.
Sprich: Der Aufrufer hat den Speicherplatz zur Verfügung zu stellen.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein du musst mit malloc neuen speicher anfordern, dort den inhalt 
reinkopieren und dann den zeiger zurückgeben.

Danach hast du aber das Problem das du den Zeiger auch wieder mit free 
freigeben musst.

Alternativ kann du der funktion test auch schon ein zeiger reingeben wo 
er den string reinkopierne soll.


void test( char* out, size_t size, const char* data )
{
   //code von oben
   strncpy( out, size, variabel mit hexdaten );
}

char[10] out;
test( out, sizeof( out ), "Hallo" );

printf("%s\n", out );

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gut danke ich probier es erstmal mit der funktion malloc und dann 
versuch ich den weg von rufus. kann ja schließlich nicht schaden alles 
beides zu verstehen. das freigeben eines speicherbereich wird ja 
sicherlich in einem Buch erklärt sein. Als Laie stelle ich mir das erst 
mal nicht so schwer vor.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Als Laie stelle ich mir das erst mal nicht so schwer vor.
ja bei dem kleinen Programm mag das auch noch gehen, wenn es mal größer 
wird und auch noch eine Fehlerbehandlung mit rein soll wird es schon 
schwerer.
Es gibt genug Programm die mit der zeit immer mehr Speicher brauchen, 
ganz trivial scheint es also nicht zu sein.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hab das jetzt auf allen beiden Wegen probiert und es hat funktioniert, 
sogar ohne das freigeben.
Mir ist trotzdem immer noch nicht ganz klar, wieso das bei Übergabe der 
lokalen Adresse nicht funktioniert hat. Eigentlich gebe ich doch die 
lokale Adresse als Wert auf einen Zeiger zurück. Wenn ich nun einen 
neuen Speicherbereich mit der Funktion malloc, der ja die Adresse des 
zurückgegebenen Strings enthält, in meiner Funktion anlege ist der 
Zeiger ja auch local. Oder ist das bei Zeigern anders. Sind Zeiger 
vielleicht ein spezieller Typ. Sehr seltsam mit den Zeigern!!!

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Mir ist trotzdem immer noch nicht ganz klar, wieso das bei Übergabe der
> lokalen Adresse nicht funktioniert hat.

Die "lokale Adresse" war die Adresse einer automatischen Variablen. 
Das sind Variablen, die innerhalb einer Funktion definiert werden. Diese 
sind nur während der Laufzeit der Funktion gültig und werden auf dem 
Stack abgelegt.

Mit Beendigung der Funktion steht der von der Funktion auf dem Stack 
belegte Speicherplatz wieder einer anderen Verwendung zur Verfügung.

malloc fordert Speicher auf dem Heap an, der ist nicht mit dem Stack zu 
verwechseln.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gast schrieb:
> hab das jetzt auf allen beiden Wegen probiert und es hat funktioniert,
> sogar ohne das freigeben.
> Mir ist trotzdem immer noch nicht ganz klar, wieso das bei Übergabe der
> lokalen Adresse nicht funktioniert hat. Eigentlich gebe ich doch die
> lokale Adresse als Wert auf einen Zeiger zurück. Wenn ich nun einen
> neuen Speicherbereich mit der Funktion malloc, der ja die Adresse des
> zurückgegebenen Strings enthält, in meiner Funktion anlege ist der
> Zeiger ja auch local. Oder ist das bei Zeigern anders. Sind Zeiger
> vielleicht ein spezieller Typ. Sehr seltsam mit den Zeigern!!!

Nicht wirklich
Es geht grundsätzlich um den Unterschied bei der Übergabe von 'normalen 
Variablen' und Arrays.
'normale Variablen' werden, sowohl in die Funktion als auch als 
Returnwert, grundsätzlich immer übergeben, indem eine Kopie des Wertes 
erzeugt wird.
int foo()
{
  int j = 5;
  return j;
}

Beim return wird nicht j selbst (als Objekt) zurückgegeben, sondern es 
wird eine Kopie des Inhalts von j (nämlich der Wert 5) zurückgegeben, 
welcher dann vom Aufrufer
  int k = foo();

seinerseits in einer Variablen abgespeichert werden kann. Hier geht also 
ein Wert über die Funktionsschnittstelle.

Arrays sind in C die grosse Ausnahme.
Wenn du ein Array an eine Funktion übergibst oder von einer Funktion ein 
Array returnierst, dann wird keine Kopie des Arrayinhaltes erzeugt, 
sondern es wird die Adresse des Arrays an die Funktion übergeben, oder 
die Funktion würde diese in einem Returnwert liefern.

Adresse ist gut. Nur muss der Arrayinhalt auch existieren, damit die 
Adresse Sinn macht.

Bei Übergabe in eine Funktion hinein ist das kein Problem. Der Aufrufer 
hat das Array und wenn er die Adresse in die Funktion hinein übergibt, 
dann existiert das Array auch weiterhin. Aber beim return ist das anders
int* foo()
{
  int k[2] = { 1, 2 };

  return k;
}

Hier wird die Adresse von k aus der Funktion heraus übergeben. 
Gleichzeitig hört aber k mit dem Ende der Funktion auf zu existieren. 
Damit hat der Aufrufer eine Adresse eines Arrays
    int* kArray = foo();

welches, wenn er auf das erste mal auf die Werte im Array zugreifen 
könnte, ganz einfach nicht mehr existiert.

Das ist ungefähr so, wie wenn ich dir die Adresse eines wahsinnig guten 
Arztes gebe. Wenn du dann an die angegebene Position hinfährst, ist das 
zugehörige Haus schon abgerissen. Möglicherweise wurde dort sogar schon 
ein neues Haus gebaut, in dem jetzt ein Steuerberater residiert. Der 
wird aber ziemlich dumm schauen, wenn du ihm deine Unterleibsbeschwerden 
schilderst.

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gast schrieb:
> Sehr seltsam mit den Zeigern!!!

:-)

Es dauert ein bisschen, bis man dahinter steigt. Ein Großteil der 
Laufzeitfehler in C-Programmen beruht auf nicht richtig initialisierten 
oder falsch veränderten Zeigern. Dafür kann man viel mit Zeigern machen 
- eben auch viel Unsinn ;-)

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Arrays sind in C die grosse Ausnahme.

Naja, was heisst ausnahme.

eigentlich ist char array[100] - abgesehen vom fix reservierten 
Speicherplatz - ja nur eine andere Schreibweise für char *array, was die 
weitere Behandlung angeht.

array[i] ist halt lesbarer als *(array+i).

Das es noch andere Unterschiede gibt, z.B. array[][] immer "rechteckig" 
ist im Gegensatz zu *array[] oder **array, ist auch klar, aber die 
Übergabe an Funktionen oder die Rückgabe ist identisch.

etwas OT:
Mir ist als einfacher Merksatz für Anfänger mal aufgefallen, wie sehr 
sich die Typengleichheit durch C zieht. Rechts muss immer das stehen, 
was links vorgegeben ist.

Z.B.
char Func(int num) {return((num+48)&0xff); }

main
{
 char val;

 val = Func(1);
}
Ist typenmässig:
(char) val = (char) ((int)(num+48)&0xff)
d.h. nach Auflösung des Funktionskopfes bleibt immer der (hoffentlich 
richtige) Typ stehen.

Kann man z.B. in diesem Beispiel sehr deutlich machen:
int (*TranslateCommand(char **argv))(int argc, char **argv);

...
int (*pCommand)(int argc, char **argv) = 0;

pCommand = TranslateCommand(argv);


Was kommt raus?
int (*pCommand)(int argc, char **argv) = int (*TranslateCommand)(int argc, char **argv)
...also ein Functionpointer vom Typ
int Function{int argc, char **argv);

Aber das grenzt schon an Magic :-)

VG,
/th.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Random ... schrieb:
>> Arrays sind in C die grosse Ausnahme.
>
> Naja, was heisst ausnahme.
>
> eigentlich ist char array[100] - abgesehen vom fix reservierten
> Speicherplatz - ja nur eine andere Schreibweise für char *array, was die
> weitere Behandlung angeht.

Nein.
Nicht schon wieder!

Du schreibst jetzt 100 mal: Arrays sind keine Pointer!

Lediglich dann, wenn der Arrayname alleine (also ohne Index) vorkommt, 
degneriert ein Array zu der Startadresse seines ersten Elements und das 
uch nicht in allen Fällen (zb sizeof). Wenn ein Array an eine Funktion 
übergeben wird, kommt der Arrayname alleine vor und daher wird 
konsequenterweise die Startadresse des Arrays übergeben.


Die Ansicht: Ein Array ist nur eine andere Schreibweise für einen 
Pointer ist schlicht und ergreifend falsch ....

a.c
int globalArray[100];

b.c
extern int * globalArray;


... hier zb. geht es mächtig in die Hose.

Erzähl einem Nueling niemals, dass Arrays eigentlich Pointer sind (egal 
in welchem Zusammenhang). Du führst ihn nur auf eine falsche Fährte.

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int i;
for (i=0; i<100; i++)
  printf("Arrays sind keine Pointer!\n");

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LOL

Arrays sind keine Pointer, jep, aber werden genau so übergeben (wie du 
ja sagst, ist der Array Name ein zeiger aufs erste element).

Oder nich?!?
:-)

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Random ... schrieb:
> ...
> Das es noch andere Unterschiede gibt, z.B. array[][] immer "rechteckig"
> ist im Gegensatz zu *array[] oder **array, ist auch klar, aber die
> Übergabe an Funktionen oder die Rückgabe ist identisch.

Das stimmt so auch nicht, man kann jeweils eine Dimension des Feldes 
ungestraft durch einen Zeiger ersetzen, mehr nicht.
[][] ist etwas anderes als **

Biespiel:
#include <stdio.h>
#include <stdlib.h>


void up_ff( int ff[][2] )
{
  printf( "ff[2][1] = %d\n", ff[2][1] );
}

void up_pp( int *pp[] )
{
  printf( "pp[2][1] = %d\n", pp[2][1] );
}



int main(void)
{
  int ff[3][2] =
    {
      { 11, 12 },
      { 21, 22 },
      { 31, 32 },
    };

  int *pp[3];
  pp[0] = (int*)malloc( 2*sizeof(int) );
  pp[0][0] = 111;
  pp[0][1] = 112;
  pp[1] = (int*)malloc( 2*sizeof(int) );
  pp[1][0] = 121;
  pp[1][1] = 122;
  pp[2] = (int*)malloc( 2*sizeof(int) );
  pp[2][0] = 131;
  pp[2][1] = 132;


  up_ff( ff );
  up_pp( pp );

  return 0;
}

So wie hier im Beispiel klappt es; es wird einmal ein
int[][]-Feld an eine Funktion übergeben und ein int**
bzw. int*[] an eine andere.

Vertauscht man aber die Parameter (also pp an up_ff()
oder ff an up_pp()) geht es schief.
Die Übergabe eines int[][] ist etwas anderes als int**.

Sehr wohl lässt sich int** durch int*[]; wie gesagt der
erste [] ist durch * ersetzbar, alle weiteren (hier nur
einer) dann nicht mehr.

> ...

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zugegeben, wo ich etwas holpere ist, wo ist der unterschied zwischen:
void func(char array[]);
void func(char *array);

main()
{
  char arr[10];
  
  func(arr);
}

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese beiden Versionen von func() sind austauschbar, weil es nur
ein eindimensionales Feld ist, und bei dieser einen und damit
ersten Dimension geht es.
Es wird in beiden Fällen der Zeiger auf das erste Element übergeben.

Dagegen in meinem obigen Beispiel mit pp und ff:
Bei ff gibt es nur die 3*2=6 Feldelemente; übergebe ich ff
an eine Funktion, wird die Adresse des ersten Elements in
ff übergeben.

Bei pp dagegen gibt es die 3 allokierten Felder (wenn man
sie so nennen mag, darum will ich mich nicht streiten),
sowie ein Feld mit Elementen jeweils vom Typ int*.
Und die Adresse des ersten dieser drei Elemente (also des
untersten der 3 int*) wird übergeben, wenn ich pp in die
Parameterliste schreibe, nicht die Adresse einer der int.

khb hat schon recht, wenn er die pauschale Aussage "Feld
gleich Zeiger" anmäkelt. Manchmal erscheinen sie austauschbar,
aber eben nicht immer.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Random ... schrieb:
> zugegeben, wo ich etwas holpere ist, wo ist der unterschied zwischen:
>
>
> void func(char array[]);
> void func(char *array);
> 

In dem Fall gibt es tatsächlich keinen Unterschied. Noch nicht mal C++ 
unterscheidet zwischen den beiden Formen. Der [] ist lediglich 
"syntaktischer Zucker" der irgendwann einmal eingeführt wurde. Das 
einzige was man der [] Schreibweise zugute halten kann, ist ein gewisser 
dokumentarischer Wert, da hier die Funktion dokumentiert, dass die 
übergebene Adresse nicht irgendein Pointer sein sollte, sondern dass die 
Funktion ihn als Anfang eines Arrays auffassen wird. Aber was hilft dir 
die 'Dokumentation', wenn sie vom Compiler zu keiner 
Datentyp-Überprüfung herangezogen wird (was allerdings auch tatsächlich 
nicht in allen Fällen möglich wäre - Stichwort dynamische Allokierung).

#include <iostream>
#include <typeinfo>

using namespace std;

void bar( int b[] )
{
   cout << typeid( b ).name() << endl;
}

void foo( int* b )
{
   cout << typeid( b ).name() << endl;
}

int main() {

   int a[] = { 1, 2 };
   int b;
   
   cout << typeid( a ).name() << endl;

   foo( a );
   bar( a );

   bar( &b );  // surprise: bar will ein Array, ich stopfe einen Pointer
               // auf kein Array rein.
}

Ausgabe:
int [2]
int *
int *
int *


Arrays waren und sind in C (und aus Kompatibilitätsgründen auch in C++) 
Bastarde, die anders funktionieren als die restlichen Datentypen ...

... mit einer klitzekleinen Ausnahme: Funktionspointer.
Bei jedem anderen Pointer muss man den Pointer dereferenziern um an das 
Objekt hinter dem Pointer zu kommen. Bei Funktionspointern kann man die 
dahinterstehende Funktion mittels
    pointer( argumente );
aufrufen, also ohne Dereferenzierung des Pointers
    (*pointer)( argumente );
Das ist zwar in der Schreibweise praktisch, aber eigentlich 
inkonsequent.

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...wie ich oben zum Thema Typen beschrieben hab :-)
Sowas gehört zu den Konstrukten, wo man sich danach zurücklehnt und 
denkt: Oha!
:-)

Autor: Suleko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich brauche eine elegante Lösung, um Hex-String nach ASCII-String 
umzuwandeln.
So etwas:  Hex-Sting "7265767679" => ASCII-String: "Hallo"

Mfg.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Suleko schrieb:
> Hallo,
> ich brauche eine elegante Lösung,

reicht auch eine nicht ganz so elegante Lösung?

Ausprogrammieren. Ist doch nicht schwer
unsigned char Digit( char digit )
{
  if( digit <= '9' )
    return digit - '0';

  return digit + 10 - 'A';
}

void ToString( const char* HexString, char* Result )
{
  while( *HexString ) {
    *Result = Digit(*HexString) + 16*Digit(*(HexString+1));
    Result++;
    HexString += 2;
  }
}

int main()
{
  char Buffer[80];

  ToString( "7265767679", Buffer );
}

[/C]

Autor: Suleko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo  Karl hein,

danke für deine Version, dachte es geht einfacher :-)
Hier ist meine Version:


string hexStr ("48616C6C6F");
string asciiStr;
int tmpHexNr=0;
int i=0;

while (i<hexStr.length()) {
  string tmpStr (hexStr, i, 2);
  sscanf  (tmpStr.c_str(), "%X", &tmpHexNr);
  char tmp = tmpHexNr;
  asciiStr += tmp;
  i +=2;
}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.