Forum: PC-Programmierung C String in Hexstring umwandeln


von Gast (Gast)


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

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Gast (Gast)


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

von Peter (Gast)


Lesenswert?

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

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?


von Random .. (thorstendb) Benutzerseite


Lesenswert?

1
lownibble = byte & 0x0f;
2
highnibble = (byte & 0xf0) >> 4;
3
4
if(0..9): lownibble += '0';
5
if(10..15): lownibble += 'a'-10;

so in der Art :-)


VG,
/th.

von Gast (Gast)


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

von Peter (Gast)


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.

von Detlev T. (detlevt)


Lesenswert?

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

Gruß, DetlevT

von Karl H. (kbuchegg)


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.

von asffrsff (Gast)


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]);
   }

von Peter (Gast)


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.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

1
    char Wort[] = "Hallo";
2
    char HexWort[100];
3
    char *pHexWort, *pWort;
4
    
5
    pHexWort = HexWort;
6
    pWort    = Wort;
7
8
    while(*pWort)
9
    {
10
       pHexWort += sprintf(pHexWort, "0x%02X ", *pWort++);
11
    }
12
13
    pHexWort = '\0';
14
    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.

von Peter (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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

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

von Random .. (thorstendb) Benutzerseite


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.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Aber wenn dir schon mal dabei sind....
1
    char *Wort = "Hallo";
2
    char *HexWort;
3
    char *pHexWort, *pWort;
4
    
5
    HexWort = (char *) malloc ((strlen(Wort)* 5 * sizeof(char)) +1);
6
    pHexWort = HexWort;
7
    pWort    = Wort;
8
9
    while(*pWort)
10
    {
11
       pHexWort += sprintf(pHexWort, "0x%02X ", *pWort++);
12
    }
13
14
    pHexWort = '\0';
15
    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.

von Peter (Gast)


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...

von Peter (Gast)


Lesenswert?

oh aufgebstellung verfehlt.

6. Setzen

Threaderstellen wollte

> char b[]= "04 F8"

als ausgabe. Nichts mit 0x..

von Karl H. (kbuchegg)


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 ' '

von Random .. (thorstendb) Benutzerseite


Lesenswert?

naguhhht:
1
    #define FORMAT   "0x%02x "
2
3
    char *Wort = "Hallo";
4
    char *HexWort;
5
    char *pHexWort, *pWort;
6
    
7
    HexWort = (char *) malloc ((strlen(Wort) * sizeof(FORMAT) * sizeof(char)) +1);
8
    pHexWort = HexWort;
9
    pWort    = Wort;
10
11
    while(*pWort)
12
    {
13
       pHexWort += sprintf(pHexWort, FORMAT, *pWort++);
14
    }
15
16
    --pHexWort = '\0';
17
    pHexWort = HexWort;
18
19
    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.

von Karl H. (kbuchegg)


Lesenswert?

1
  ...
2
   * sizeof(FORMAT)
3
  ...

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



1
   --pHexWort = '\0';

Probier das mal mit
    char *Wort = "";

aus :-)

von Random .. (thorstendb) Benutzerseite


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.

von Gast (Gast)


Lesenswert?

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

von Random .. (thorstendb) Benutzerseite


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 :-)
1
#define FORMAT   "0x%02x "
2
3
    char *Wort = "Hallo";
4
    char *HexWort;
5
    char *pHexWort, *pWort;
6
    
7
    HexWort = (char *) malloc ((strlen(Wort) * sizeof(FORMAT) * sizeof(char)) +1);
8
    pHexWort = HexWort;
9
    pWort    = Wort;
10
11
    while(*pWort)
12
    {
13
       pHexWort += sprintf(pHexWort, FORMAT, *pWort++);
14
    }
15
16
    if(pHexWort> HexWort) *(--pHexWort) = '\0';
17
    else *pHexWort = '\0';
18
19
    pHexWort = HexWort;
20
21
    while(*pHexWort) fputc(*pHexWort++, stdout);

von Karl H. (kbuchegg)


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.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

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

1
    #define FORMAT         "0x%02x "
2
    #define HEX_NUM_CHARS  5
3
4
    char *Wort = "Hallo";
5
    char *HexWort;
6
    char *pHexWort, *pWort;
7
    
8
    HexWort = (char *) malloc ((strlen(Wort) * HEX_NUM_CHARS * sizeof(char)) +1);
9
    pHexWort = HexWort;
10
    pWort    = Wort;
11
12
    while(*pWort)
13
    {
14
       pHexWort += sprintf(pHexWort, FORMAT, *pWort++);
15
    }
16
17
    if(pHexWort> HexWort) *(--pHexWort) = '\0';
18
    else *pHexWort = '\0';
19
20
    pHexWort = HexWort;
21
22
    while(*pHexWort) fputc(*pHexWort++, stdout);

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


Lesenswert?

> da ich ja noch an was anderem arbeite **g**

Da gehts dir wie mir.  ggggg

von Random .. (thorstendb) Benutzerseite


Lesenswert?

jepp, haste recht.
So was testet man aber idR. beim Funktionseintritt.

von Random .. (thorstendb) Benutzerseite


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 :-)

von Gast (Gast)


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  ;
}

von Peter (Gast)


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.

von Gast (Gast)


Lesenswert?

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

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Peter (Gast)


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 );

von Gast (Gast)


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.

von Peter (Gast)


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.

von Gast (Gast)


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!!!

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Karl H. (kbuchegg)


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.
1
int foo()
2
{
3
  int j = 5;
4
  return j;
5
}

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
1
  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
1
int* foo()
2
{
3
  int k[2] = { 1, 2 };
4
5
  return k;
6
}

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
1
    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.

von Mark B. (markbrandis)


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 ;-)

von Random .. (thorstendb) Benutzerseite


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.
1
char Func(int num) {return((num+48)&0xff); }
2
3
main
4
{
5
 char val;
6
7
 val = Func(1);
8
}
Ist typenmässig:
1
(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:
1
int (*TranslateCommand(char **argv))(int argc, char **argv);
2
3
...
4
int (*pCommand)(int argc, char **argv) = 0;
5
6
pCommand = TranslateCommand(argv);

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

Aber das grenzt schon an Magic :-)

VG,
/th.

von Karl H. (kbuchegg)


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
1
int globalArray[100];

b.c
1
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.

von Mark B. (markbrandis)


Lesenswert?

1
int i;
2
for (i=0; i<100; i++)
3
  printf("Arrays sind keine Pointer!\n");

von Random .. (thorstendb) Benutzerseite


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?!?
:-)

von Klaus W. (mfgkw)


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:
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
5
void up_ff( int ff[][2] )
6
{
7
  printf( "ff[2][1] = %d\n", ff[2][1] );
8
}
9
10
void up_pp( int *pp[] )
11
{
12
  printf( "pp[2][1] = %d\n", pp[2][1] );
13
}
14
15
16
17
int main(void)
18
{
19
  int ff[3][2] =
20
    {
21
      { 11, 12 },
22
      { 21, 22 },
23
      { 31, 32 },
24
    };
25
26
  int *pp[3];
27
  pp[0] = (int*)malloc( 2*sizeof(int) );
28
  pp[0][0] = 111;
29
  pp[0][1] = 112;
30
  pp[1] = (int*)malloc( 2*sizeof(int) );
31
  pp[1][0] = 121;
32
  pp[1][1] = 122;
33
  pp[2] = (int*)malloc( 2*sizeof(int) );
34
  pp[2][0] = 131;
35
  pp[2][1] = 132;
36
37
38
  up_ff( ff );
39
  up_pp( pp );
40
41
  return 0;
42
}

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.

> ...

von Random .. (thorstendb) Benutzerseite


Lesenswert?

zugegeben, wo ich etwas holpere ist, wo ist der unterschied zwischen:
1
void func(char array[]);
2
void func(char *array);
3
4
main()
5
{
6
  char arr[10];
7
  
8
  func(arr);
9
}

von Klaus W. (mfgkw)


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.

von Karl H. (kbuchegg)


Lesenswert?

Random ... schrieb:
> zugegeben, wo ich etwas holpere ist, wo ist der unterschied zwischen:
>
>
1
> void func(char array[]);
2
> void func(char *array);
3
>

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).

1
#include <iostream>
2
#include <typeinfo>
3
4
using namespace std;
5
6
void bar( int b[] )
7
{
8
   cout << typeid( b ).name() << endl;
9
}
10
11
void foo( int* b )
12
{
13
   cout << typeid( b ).name() << endl;
14
}
15
16
int main() {
17
18
   int a[] = { 1, 2 };
19
   int b;
20
   
21
   cout << typeid( a ).name() << endl;
22
23
   foo( a );
24
   bar( a );
25
26
   bar( &b );  // surprise: bar will ein Array, ich stopfe einen Pointer
27
               // auf kein Array rein.
28
}

Ausgabe:
1
int [2]
2
int *
3
int *
4
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
1
    pointer( argumente );
aufrufen, also ohne Dereferenzierung des Pointers
1
    (*pointer)( argumente );
Das ist zwar in der Schreibweise praktisch, aber eigentlich 
inkonsequent.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

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

von Suleko (Gast)


Lesenswert?

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

Mfg.

von Karl H. (kbuchegg)


Lesenswert?

Suleko schrieb:
> Hallo,
> ich brauche eine elegante Lösung,

reicht auch eine nicht ganz so elegante Lösung?

Ausprogrammieren. Ist doch nicht schwer
1
unsigned char Digit( char digit )
2
{
3
  if( digit <= '9' )
4
    return digit - '0';
5
6
  return digit + 10 - 'A';
7
}
8
9
void ToString( const char* HexString, char* Result )
10
{
11
  while( *HexString ) {
12
    *Result = Digit(*HexString) + 16*Digit(*(HexString+1));
13
    Result++;
14
    HexString += 2;
15
  }
16
}
17
18
int main()
19
{
20
  char Buffer[80];
21
22
  ToString( "7265767679", Buffer );
23
}

[/C]

von Suleko (Gast)


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;
}

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.