Führende Null



  • Hallo,

    ich habe dieses Programm das mir die MAC Adresse ausgibt.

    int sock_fd = socket( AF_INET , SOCK_DGRAM , 0 );
        if( sock_fd == -1 ) { printf("Error: creating socket.\n"); exit(1); }
        struct ifreq ifr;
        strcpy( ifr.ifr_name , "eth1" );
        if( ioctl( sock_fd , SIOCGIFHWADDR , &ifr ) == -1 ) { printf("problems with ioctl.\n"); exit(1); }
        printf("%s\n" , ether_ntoa( (struct ether_addr*) ifr.ifr_hwaddr.sa_data ) );
        close( sock_fd );
    

    Dabei habe ich das Problem das beim Ausgeben die führende Null wegfällt. Also sieht das dann ungefähr so aus:

    0:2:e4:32:12:23
    und eigentlich sollte sie so aussehen
    00:02:e4:32:12:23

    Wie kann ich das nun bei diesem Beispiel lösen? Die MAC Adresse sollte übrigens nicht nur ausgegeben werden sondern auch in einem std::string gespeichert werden.

    Danke im voraus.

    c-newbie



  • Stammt die Funktion ether_ntoa von dir? Wenn ja, zeig mal den Code.

    Allgemein: Du mußt bei der Ausgabe das Format richtig einstellen, damit du dein Ergebnis bekommst - bei printf() und Co. gehr das mit "%02x", bei IOStreams über setfill() und setw() Manipulatoren.



  • Die Funktion ether_ntoa stammt nicht von mir. Die wird über eine standard Include Datei eingebunden.

    Ich habe es bereits so ausprobiert. Aber leider klappt das nicht.

    ostringstream ostr;
    ostr << hex << setfill ('0');
    
        ostr << setw(2) << ether_ntoa( (struct ether_addr*) ifr.ifr_hwaddr.sa_data )
     ;
    test = ostr.str();
     cout << test << endl;
    


  • So, wie's aussieht, schreibt diese Funktion dein MAC-Adresse schon in String-Format, also mußt du eventuelle Anpassungen auch in der Funktion vornehmen. Alternativ bleibt dir noch die Möglichkeit, die Adresse direkt auszulesen und von Hand zu formatieren (irgendwo in den Dokumentationen sollte auch stehen, wie genau die struct's aufgebaut sind).



  • Danke für die Antwort.

    Ich habe nun ein Beispiel gefunden bei mit dieser Ausgabe die MAC Adresse ausgegeben wird.
    Hab es leider nicht geschafft das in einen std::string zu kriegen.

    printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
                                    (unsigned char)buf[intrface].ifr_hwaddr.sa_data[0],
                                    (unsigned char)buf[intrface].ifr_hwaddr.sa_data[1],
                                    (unsigned char)buf[intrface].ifr_hwaddr.sa_data[2],
                                    (unsigned char)buf[intrface].ifr_hwaddr.sa_data[3],
                                    (unsigned char)buf[intrface].ifr_hwaddr.sa_data[4],
                                    (unsigned char)buf[intrface].ifr_hwaddr.sa_data[5]);
    

    Vielleicht kann mir jemand Helfen.

    nixchecker



  • std::string bla;
    bla += (unsigned char)buf[intrface].ifr_hwaddr.sa_data[0];
    bla += (unsigned char)buf[intrface].ifr_hwaddr.sa_data[1];
    bla += (unsigned char)buf[intrface].ifr_hwaddr.sa_data[2];
    bla += (unsigned char)buf[intrface].ifr_hwaddr.sa_data[3];
    bla += (unsigned char)buf[intrface].ifr_hwaddr.sa_data[4];
    bla += (unsigned char)buf[intrface].ifr_hwaddr.sa_data[5];



  • Ja das hatte ich auch schon ausprobiert aber da erhalte ich anstatt der MAC Adresse nur das:

    ã

    Danke

    nixchecker



  • Deine Vorgehensweise mit dem stringstream war schon fast richtig

    #include <iomanip>
    
    using namespace std;
    
    ostringstream ostr;
    
    for(int i=0; i<6; i++)
       ostr << hex << setfill('0') << setw(2)
            << static_cast<int>(buf[intrface].ifr_hwaddr.sa_data[i]);
    
    const std::string &s = ostr.str();
    


  • Danke für deine Antwort.

    Ich hab das nun ausprobiert und die Ausgabe stimmt auch schon fast.

    Allerdings sind in der MAC Adresse noch einige "f" vorhanden.

    Also sieht die Ausgabe so aus:

    0002ffffffe501ffffff99ffffff91

    Ich hatte alles genau so drin außer das ich anstatt von einem const string einen string benutze habe.

    nixchecker



  • Ok, die Struktur scheint 'char' statt 'unsigned char' zu benutzen (wäre gut, wenn du die Struktur gepostet hättest - ansonsten können wir ja nur raten -)

    Also mußt du erst noch nach 'unsigned char' casten (da negative Werte z.B. -1 als ffffffff interpretiert werden):

    static_cast<unsigned int>(static-cast<unsigned char>(buf[intrface].ifr_hwaddr.sa_data[i]));
    

    Evtl. geht auch direkt nach 'unsigned int' casten -- probiere es mal aus...

    Ich sehe gerade, daß noch die ':' dazwischen fehlen, aber das sollte ja kein Problem sein...



  • Oder auch so:

    char buffer[32];
    sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
        int(buf[intrface].ifr_hwaddr.sa_data[0]) & 0xFF,
        int(buf[intrface].ifr_hwaddr.sa_data[1]) & 0xFF,
        int(buf[intrface].ifr_hwaddr.sa_data[2]) & 0xFF,
        int(buf[intrface].ifr_hwaddr.sa_data[3]) & 0xFF,
        int(buf[intrface].ifr_hwaddr.sa_data[4]) & 0xFF,
        int(buf[intrface].ifr_hwaddr.sa_data[5)) & 0xFF);
    
    std::string s = buffer;
    

    oder so

    boost::format fmt("%02x:%02x:%02x:%02x:%02x:%02x");
    for (size_t i = 0; i < 6; i++)
        fmt % (int(buf[intrface].ifr_hwaddr.sa_data[i]) & 0xFF);
    std::string s = fmt.str();
    


  • Ok vielen Dank für die Hilfe.

    Ich hab das nun mit sprintf gelöst hat wunderbar geklappt.

    Danke.

    nixchecker



  • Da bietet man eine saubere C++ Lösung an und hustbaer fällt wieder in alte C Zeiten zurück (die boost-Variante ist natürlich ebenso genehmigt, aber leider benutzen die meisten Leute es nicht)...



  • std::ostringstream ss;
    ss  << std::hex << std::setw(2) << std::setfill('0') << (static_cast<int>(buf[intrface].ifr_hwaddr.sa_data[0]) & 0xFF) << ":"
        << std::hex << std::setw(2) << std::setfill('0') << (static_cast<int>(buf[intrface].ifr_hwaddr.sa_data[1]) & 0xFF) << ":"
        << std::hex << std::setw(2) << std::setfill('0') << (static_cast<int>(buf[intrface].ifr_hwaddr.sa_data[2]) & 0xFF) << ":"
        << std::hex << std::setw(2) << std::setfill('0') << (static_cast<int>(buf[intrface].ifr_hwaddr.sa_data[3]) & 0xFF) << ":"
        << std::hex << std::setw(2) << std::setfill('0') << (static_cast<int>(buf[intrface].ifr_hwaddr.sa_data[4]) & 0xFF) << ":"
        << std::hex << std::setw(2) << std::setfill('0') << (static_cast<int>(buf[intrface].ifr_hwaddr.sa_data[5]) & 0xFF);
    std::string s = ss.str();
    

    und schon ist boost und clibrary weg 🙂



  • (D)Evil, das hatten wir ja schon (auf der ersten Seite).
    Nur hatte ich dazu eine Schleife benutzt, und keinen Copy & Paste-Fehler drin (ätsch...)



  • Hätte auch ne Schleife genommen, wäre dann nicht ne dumme if nötig um zu gucken ob nen : hin soll, oder nicht 😛


Anmelden zum Antworten