Ausgabe eines char[] mit printf



  • Danke für deine Antwort.

    Ich habe gerade getestet und habe fflash(stdout) noch eingefügt. Die Ausgabe bleibt die selbe. Aber du hast natürlich recht. Den Teil mit "Empfangene Daten" habe ich gerade unterschlagen.

    Die Ausgabe sieht dann so aus:

    Empfangene Daten: ffffff81
    

    Erwartet habe ich auch ein

    Empfangene Daten: 81
    

    Ich habe gerade mal noch weiter im Forum gesucht. Dort gab es so ein Problem auch schon einmal. Dort ging es um signed/unsigned char. Ich habe gerade mal einen Typecast char->unsigned char durchgeführt. Dann bekomme ich dann auch nur die 81 ausgegeben.

    Scheint also irgendwo aus dem char zu kommen.
    Kann man das unterdrücken?

    Danke

    Sledge77



  • schreib unsigned char anstatt signed, wenn du keine negativen zahlen willst.

    unsigned char buf1[1024]; 
     char buf2[1024];
     buf1[0] = 1;
     buf2[0] = -1;
    
     printf("Empfangene Daten: %02x\n",buf1[0]); 
     printf("Empfangene Daten: %02x\n",buf2[0]); 
    
     printf("char max: %4d %-X\n", CHAR_MAX, CHAR_MAX ); 
     printf("char min: %4d %-X\n", CHAR_MIN, CHAR_MIN ); 
     printf("unsigned char max: %4d %-X\n", UCHAR_MAX, CHAR_MIN );
    


  • axoh, vielleicht hätte ich noch schreiben sollen, das du an die konstanten mit
    [cpp]
    #include <limits.h>
    [/code]
    rankommst.



  • Das habe ich schon versucht. Das Problem ist das die verwendeten Funktion (sockets, winsock) dieses Unsigned nicht nehmen. Also wäre dort "jedesmal" ein Typecast erforderlich. Kann man das noch umgehen?

    /Sledge77



  • das brauchst du nicht zu umgehen, weil es an der internen darstellung der bits nichts ändert.



  • Wie meinst du das?

    Ich gestehe das ich dich nicht ganz verstanden habe.



  • 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