Ausgabe eines char[] mit printf



  • warum möchtest den datentypen ändern ?



  • Ich habe momentan folgenden Code:

    ..
      char buf[1024];
    ..
      rc=recvfrom(s,buf,sizeof(buf),0,(SOCKADDR*)&remoteAddr,&remoteAddrLen);
    ..
      printf("Empfangene Daten: %02x\n",buf[0]);
    ..
    

    Wenn ich diesen Code verwende bekomme ich o.g. Ausgabe

    Empfangene Daten: ffffff81
    

    Wenn ich nun die Definition ändere:

    ..
      unsigned char buf[1024];
    ..
      rc=recvfrom(s,buf,sizeof(buf),0,(SOCKADDR*)&remoteAddr,&remoteAddrLen);
    ..
      printf("Empfangene Daten: %02x\n",buf[0]);
    ..
    

    bekomme ich folgenden Compilerfehler:

    D:\Projekte\getudp\main.cpp|104|error: invalid conversion from `unsigned char*' to `char*'|
    

    Erst wenn ich die Zeile

    rc=recvfrom(s,buf,sizeof(buf),0,(SOCKADDR*)&remoteAddr,&remoteAddrLen);
    

    in

    rc=recvfrom(s,(char*)buf,sizeof(buf),0,(SOCKADDR*)&remoteAddr,&remoteAddrLen);
    

    ändere kann ich den Code kompilieren.

    Und wenn ich dich richtig verstanden habe geht es ja darum char durch unsigned char zu ersetzen.



  • z.b. 0xF5 hexadezimal , ist binär 1111 0101
    wenn du schreibst char c = 0xF5 dann ist es intern 1111 0101

    wenn in deinem char also 1111 0101 drin steckt dann
    bleibt es auch drin, wenn du schreibst unsigned char a = c

    ich sehe gerade, du kompilierst eine *.cpp datei, vermutlich geht das casten in c++ nicht.
    in c geht das. wenn du die dateiendung in *.c änderst, müsste das gehen.

    im übrigen spricht nichts dagegen, die daten mit char buf[1024] zu empfangen und dann später zu casten, wenn es sein muss.



  • aaaaaach da fällt mir gerade ein:
    wieso guckst du dir eigentlich den empfangenen inhalt hexadezimal an ?

    guck mal:

    printf("%c %d %X\n",  0xffffff81, 0xffffff81, 0xffffff81 );
    

    drei mal die gleiche bitfolge, unterschiedlich interpretiert.
    das meinte ich mit interner bit-darstellung



  • Was mich bei der ganzen Sache nur wundert ist das ich ja nicht den ffffff81 aus dem Netz bekomme sondern eigentlich die 81. Warum wird das gedreht/verändert?
    Bei der Darstellung würde ich ein 00000081 dann noch verstehen.



  • bei dir ist 'char' signed und deshalb wird 0x81 als negative zahl interpretiert. printf erweitert den 'char' zu einem 'int', wobei der (negative) wert erhalten bleibt. daher siehste 0xffffff81.
    🙂



  • Aber ein if der Form

    if (buf[0]==0x81) printf("Test\n");
    

    müsste dann doch funktionieren. Oder?
    Das tuts nämlich auch nicht.

    Erst wenn ich folgende if Abfrage verwende

    if (buf[0]==0xffffff81) printf("Test\n");
    

    funktionierts.



  • Sledge77 schrieb:

    if (buf[0]==0x81) printf("Test\n");
    

    mach's so:

    if (buf[0]==(char)0x81) printf("Test\n");
    

    oder nimm am besten 'unsigned char'
    🙂



  • unsigned char kann ich leider nicht verwenden. Jedenfalls nicht von anfang an, da die WinSock Funktionen einen char* erwarten.

    Recht viel typecast was mich dann erwartet.

    Schade. Ich dachte vielleicht hätte jemand noch eine einfache Lösung dafür.

    Danke für eure schnelle Hilfe.

    Falls jemandem noch etwas einfällt...

    Danke



  • Ok, nun habe ich dein Problem verstanden.

    bei einem

    char c = 0x81; printf("%x", c);
    

    wird c, welches ja ein char ist, in einen unsigned int gecastet und dann
    ausgegeben. Ein %x erwartet einen unsigned integer. Da deine empfangenen
    Daten negativ sind, sprich das höchste Bit gesetzt ist, wird beim
    Konvertieren in den unsigned int die f's vorangesetzt.

    zu deinem Beispiel:

    0x81 (hex) = 1000 0001 (binär) = 129 (unsigned char) = -127 (signed char)
    -127 (signed char) = 0xffffff81 (hex, int)
    

    So entstehen diese f's.

    Ich würde weiter mit char* arbeiten und nur dann, wenn ich es brauche
    in den entsprechenden Datentyp casten.

    Gruß mcr



  • Danke für die Info



  • mcr schrieb:

    Ich würde weiter mit char* arbeiten und nur dann, wenn ich es brauche
    in den entsprechenden Datentyp casten.

    nee, das ist dumm wenn man eigentlich mit uint8_t arbeiten will (siehe z.b. den missglückten vergleich). aber vielleicht kann er seinem compiler sagen, dass 'char' unsigned sein soll.
    🙂



  • Vielleicht sollte ich mal was zu meiner Aufgabenstellung sagen.

    Also.

    Ich bekomme per UDP Nachrichten zugeschickt. Diese muss ich Byte für Byte zerlegen und anhand dessen dann entscheiden wie es in dem Programm weitergeht. Mein Problem war also das ich Vergleiche nicht durchführen konnte (switch-case).
    Gelöst habe ich es nun folgendermaßen:

    char buf[1024];
    .
    .
    rc=recvfrom(s,buf,sizeof(buf),0,(SOCKADDR*)&remoteAddr,&remoteAddrLen);
    .
    .
    switch ((unsigned char)buf[0])
    {
    case 0x81:
       printf("Passt\n");
       break;
    default:
       printf("Nichts\n");
    }
    

    Wobei hier natürlich dann mehrere cases vorkommen können. Mit dieser Lösung kann ich dann eigentlich leben. Wenn es noch etwas besseres gibt sagts mir.


Anmelden zum Antworten