Übergabe eines CharArray, der Registern gelesen wird
-
Ich habe ein Problem mit der Übergabe eines Char Array. Was ich möchte: Die MAC-Adresse meines Controllers in einen 6Byte langen Array schreiben.
Die Adresse wird aus zwei Registern gelesen und konvertiert. Bildschirmausgabe in der Funktion liefert auch die richtigen Werte. Nur mit der Übergabe klappt es noch nicht. Die ausgelesene Adresse soll später als Parameter an eine andere noch zu schreibende Funktion übergeben werden.Bei Ausgabe im Hauptprogramm wird der Variablenwert nicht ausgegen. Kann ich einen globalen Array wie unten im Code gezeigt bearbeiten. Hat kann jemand mir einen Hinweis geben, warum ich keine Ausgabe bekomme, bzw wie ich diesen Array am Besten übergebe. Ich bin etwas verunsichert, da meine Freundschaft mit den Zeigern noch auf wackeligen Füßen steht. Bin für jede Hilfe dankbar.
void macauslesen(char *macaddr [6]){ char maclow[10];//MacAdresse Teil1 char machigh[10];//MacAdresse Teil2 int i; char nullzeichen[]="01";//Gewünscht ist eingentlich nur eine 0 die vorne eingefügt wird. Bessere Idee? sprintf(maclow, "%x",*pMacAdressLowBytes);//Register mit ersten 4Byte der MAC-Adresse while (strlen(maclow)<8){ //Wenn nötig Nullen vorne Einfügen um korrekte Anzeige zu erhalten for (i=strlen(maclow)+1;i>0;i--){ maclow[i]=maclow[i-1]; } maclow[0]=nullzeichen[0]; } sprintf(machigh, "%x",*pMacAdressHighBytes);//Register mit letzen 2Byte der MAC-Adresse while (strlen(machigh)<8){ //Wenn nötig Nullen vorne Einfügen um korrekte Anzeige zu erhalten for (i=strlen(machigh)+1;i>0;i--){ machigh[i]=machigh[i-1]; } machigh[0]=nullzeichen[0]; } macaddr [0]=HexToNbr(maclow[0])*16+HexToNbr(maclow[1]);//Hier erhalte ich Warnungen: Makes Pointer from Integer without a cast. macaddr [1]=HexToNbr(maclow[2])*16+HexToNbr(maclow[3]);//Mit printf macaddr [x] bekomme ich aber den Richtigen Wert heraus macaddr [2]=HexToNbr(maclow[4])*16+HexToNbr(maclow[5]);//Habe anstatt *16 auch 4 Byte Linksschieben probiert, macaddr [3]=HexToNbr(maclow[6])*16+HexToNbr(maclow[7]);//aber keine Richtigen Werte erhalten macaddr [4]=HexToNbr(machigh[0])*16+HexToNbr(machigh[1]); macaddr [5]=HexToNbr(machigh[2])*16+HexToNbr(machigh[3]); } int main(void){ char DA [6]; char SA [6] char *quellmac; macauslesen(SA);//QuellMAC printf ("SA = %s ", SA);
Restlicher Code
// Konvertiere Hexzahl in Zahl char HexToNbr(const char cHex) { if (cHex>=48 && cHex<=57) { return cHex-48; } else if(cHex>=65 && cHex<=70) { return 10+cHex-65; } else if(cHex>=97 && cHex<=102) { return 10+cHex-97; } }
-
Du willst ein char-Array übergeben - tatsächlich übergibst du aber ein Array von char-Zeigern. Korrekt lautet die Funktion entweder
void macauslesen(char *macaddr)
odervoid macauslesen(char macaddr[6])
(beides ist äquivalent)PS: Die Längenkorrektur der Ausgaben kannst du dir sparen, wenn du die richtigen Formatkennungen verwendest:
sprintf(maclow, "%08x",*pMacAdressLowBytes);
(und anstelle der Magic Numbers in der HexToNbr() würde ich lieber char-Literale verwenden)
-
Danke für deine schnelle Antwort!
Das mit den Char Literalen war mir neu. Ich habe mich kundig gemacht und wenn ich es richtig verstanden habe meinst du ich soll anstatt:
macaddr [1] = HexToNbr(maclow[2])*16+HexToNbr(maclow[3]);
macaddr [1] = 'maclow[2]' +'maclow[3]';
verwenden.
Der Compiler meldet sich dann aber mit: "integer overflow in expression" "character constant too long for its type" und " overflow in implicit constant conversion" und das Ergebniss ist auch nicht korrekt.
Oder wie meinst du dass mit den Literalen?Leider habe außerdem noch ein Problem: Wenn ich die Variablen zum Test ausgebe erhalte ich für
printf("macaddr1 %x ",macaddr[1]);
"macaddr1 ffffffaa"
printf("macaddr2 %x ",macaddr[2]);
"macaddr2 ffffffbb
Wie passt so ein Wert ffffffaa überhaupt in ein char rein und wieso erhalte ich nicht aa und bb als Ergebnis?
Dabei lautet die MAC z.B.: 00:aa:bbdd:ee
-
cgaw25 schrieb:
Das mit den Char Literalen war mir neu. Ich habe mich kundig gemacht und wenn ich es richtig verstanden habe meinst du ich soll anstatt:
macaddr [1] = HexToNbr(maclow[2])*16+HexToNbr(maclow[3]);
macaddr [1] = 'maclow[2]' +'maclow[3]';
verwenden.
Da hast du mich offenbar nicht richtig verstanden - der Aufruf war schon in Ordnung, aber die Funktionsdefinition war ein wenig kryptisch.
schönere Lösung:
char HexToNbr(const char cHex) { if (isdigit(cHex)) { return cHex-'0'; } else if(cHex>='a' && cHex<='f') { return 10+cHex-'a'+10; } else if(cHex>='A' && cHex<='A') { return 10+cHex-'A'+10; } }
Leider habe außerdem noch ein Problem: Wenn ich die Variablen zum Test ausgebe erhalte ich für
printf("macaddr1 %x ",macaddr[1]);
"macaddr1 ffffffaa"
printf("macaddr2 %x ",macaddr[2]);
"macaddr2 ffffffbb
Wie passt so ein Wert ffffffaa überhaupt in ein char rein und wieso erhalte ich nicht aa und bb als Ergebnis?
Dabei lautet die MAC z.B.: 00:aa:bbdd:ee
char ist (bei dir) vorzeichenbehaftet und das sind 0xAA und 0xBB negative Werte - die bei der "integral promotion" zu wertgleichen int's aufgefüllt werden. Wenn dich das stört, arbeite lieber mit 'unsigned char'.
*grübelt* übrigens kannst du dir die gesamte Umrechnerei über die String-Form ersparen - du kannst deine Eingabe-Register auch mit Bit-Operatoren zerlegen:
macaddr[0] = (*pMacAdressLowBytes>>24) & 0xFF; macaddr[1] = (*pMacAdressLowBytes>>16) & 0xFF; macaddr[2] = (*pMacAdressLowBytes>> 8) & 0xFF; macaddr[3] = *pMacAdressLowBytes & 0xFF; macaddr[4] = (*pMacAdressHighBytes>>8) & 0xFF; macaddr[5] = *pMacAdressHighBytes & 0xFF;
-
cgaw25 schrieb:
Wenn ich die Variablen zum Test ausgebe erhalte ich für
printf("macaddr1 %x ",macaddr[1]);
"macaddr1 ffffffaa"
printf("macaddr2 %x ",macaddr[2]);
"macaddr2 ffffffbb
die werte werden bei der übergabe an printf zu int erweitert und wenn dann bit 7 gesetzt ist, geht compilerchen davon aus, einen negativen wert vor sich zu haben. das array ist wohl ein 'char[]'? mach 'unsigned char[]' daraus, dann sollte es gehen.
-
Ja ihr habt recht, das war die Ursache.Läuft alles wie es soll. Danke für die schnellen Antworten.
Damit ich mir beim nächsten mal nicht wieder die Gehirnwindungen verbiege um Code für eigenltich nicht notwendige Funktionen zu schreiben möchte ich euch noch fragen was %08x genau bewirkt
CStoll schrieb:
PS: Die Längenkorrektur der Ausgaben kannst du dir sparen, wenn du die richtigen Formatkennungen verwendest: [c]sprintf(maclow, "%08x",*pMacAdressLowBytes);[/c]
(und anstelle der Magic Numbers in der HexToNbr() würde ich lieber char-Literale verwenden)Bei http://www.galileo-press.de/openbook/c_von_a_bis_z/c_007_012.htm 7.13 habe ich folgendes gefunden: 0 Bei numerischer Ausgabe wird mit Nullen bis zur angegebenen Weite aufgefüllt.
Verstehe ich das richtig: Wenn ich z.B. einen String habe, der 5 Byte lang ist macht mir die Angabe %08 einen String, der 8 Byte lang ist und setzt vorne 3 Nullen dran. Werden die Nullen immer vorne dran gehangen?
-
Ja, werden sie - hintendran macht's schließlich wenig Sinn