【问题标题】:How do you convert a MAC address (in an array) to string in C?如何将 MAC 地址(在数组中)转换为 C 中的字符串?
【发布时间】:2013-05-09 04:06:52
【问题描述】:

如何将int 数组中的 MAC 地址转换为 C 中的字符串?例如,我使用以下数组来存储 MAC 地址:

int array[6] = {0x00, 0x0d, 0x3f, 0xcd, 0x02, 0x5f};

如何将其转换为字符串,例如"00:0d:3f:cd:02:5f"

【问题讨论】:

  • (s)(sn)printf() 是你的朋友。
  • 一个int 对应 MAC 地址的每个字节? O.o
  • 我知道,有点大!
  • @Mike int 是一个有效的选择,许多 C API 使用整数作为字节。也许您想允许无效的 MAC 地址。 (并不是说没有其他方法可以做到)。
  • @AdrianRatnapala,但您可以只使用uint64_t,每个 MAC 地址使用 8 个字节而不是 24 个! =)

标签: c arrays string


【解决方案1】:

你可以这样做:

char macStr[18];
int array[6] = {0x00, 0x0d, 0x3f, 0xcd, 0x02, 0x5f};

snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
         array[0], array[1], array[2], array[3], array[4], array[5]);

如果你想要一个大写的字符串,使用大写的'X':

snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X",
         array[0], array[1], array[2], array[3], array[4], array[5]);

【讨论】:

  • 在我的 MVSC 构建中,这实际上为第三个参数产生了 3FFFFFFF。格式 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx" 解决了这个问题
  • 有没有一种简单的方法可以在构造字符串时将字符串全部大写,或者这是一个单独的步骤?我知道strupr(),但它只适用于字符串。
【解决方案2】:
unsigned char array[6] = {0x00, 0x0d, 0x3f, 0xcd, 0x02, 0x5f};//or BYTE

char str[19];
sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x",array[0], 
        array[1], array[2], array[3], array[4],array[5]);

【讨论】:

  • 你说得对,谢谢,我注意到了,我会改变它。
  • -1 因为如果数组中的ints 太大,这会溢出str
  • 数组大小只要18即可。只要数组是unsigned char类型,就不可能溢出。 (顺便说一句,我总是使用 snprintf 来确定)。此外,对于那些将其作为参考的人,gcc 还允许使用 %02hhx 格式说明符来处理带符号字符数组的负数。
【解决方案3】:

没有使用 snprintf,但这只是为了好玩....

#define MAC_LEN 6

static const char _mac[MAC_LEN] = { 0xBC, 0xDD, 0xC2, 0xF0, 0x2E, 0x06 };

int main(void){

char mac[MAC_LEN*2 + 1] = {0}; // added null char

int j = 0;
for( int i = 0;  i < sizeof(_mac) ; i++ )
{
    j = i * 2;
    mac[j] = (((_mac[i] & 0xF0)>>4)&0xF) ;
    mac[j] += (mac[j] <= 9) ? '0' : ('A' - 10);
    j++;
    mac[j] = (_mac[i] & 0x0F);
    mac[j] += (mac[j] <= 9) ? '0' : ('A' -10);
}

printf("Hello World!, my mac address : %s\n", mac);

fflush(stdout);

return 0;
}

【讨论】:

  • 太棒了!正是我想要的
【解决方案4】:

首先,您可能需要调整用于存储 MAC 地址的类型。我认为unsigned char 在这种情况下更好。接下来,我建议您创建一个函数来写入 MAC 地址,这样您就不会在代码中的任何地方复制和粘贴相同的 printf() 语句并调整您正在索引的数组。 (此外,它还允许编译器根据函数参数检查您使用的类型,以确保它是正确的。)

这里既有类似inet_ntoa()的不可重入解决方案,也有类似inet_ntoa_r()的重入解决方案:

#include <stdio.h>

unsigned char mac[6] = {0x00, 0x0d, 0x3f, 0xcd, 0x02, 0x5f};

char* MACADDR_toString(unsigned char* addr)
{
    static char str[18];

    if(addr == NULL) return "";

    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", 
             addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);

    return str;
}

char* MACADDR_toString_r(unsigned char* addr, char* str, size_t size)
{
    if(addr == NULL || str == NULL || size < 18) return NULL;

    snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x", 
             addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);

    return str;
}

int main(int argc, char* argv[])
{
    char str[18];
    printf("%s\n", MACADDR_toString(mac));
    printf("%s\n", MACADDR_toString_r(mac, str, sizeof(str)));
    return 0;
}

【讨论】:

  • -1 表示不可重入解决方案,+1 表示发现它是不可重入的 ;-)
  • @Roddy,好的,好的,我为你添加了一个可重入版本。 ;-)
【解决方案5】:

如果您正在处理无法使用 stdlib 功能的低级内核或驱动程序,则可以按如下方式进行转换-

#include <stdio.h>

struct ether_addr{
    int ether_addr_octet[6];
};

const char* ntoa(struct ether_addr ea)
{
    static char mstr[13];
    int j=11;
    for (int i=5;i>=0;i--)
    {
        int val = ea.ether_addr_octet[i];
        while (val)
        {
            int k = val%16;
            if (k==10)
                mstr[j--] = 'A';
            if (k==11)
                mstr[j--] = 'B';
            if (k==12)
                mstr[j--] = 'C';
            if (k==13)
                mstr[j--] = 'D';
            if (k==14)
                mstr[j--] = 'E';
            if (k==15)
                mstr[j--] = 'F';
            if (k<10)
                mstr[j--] = k + '0';
            val = val/16;
        }
    }
    mstr[12] = '\0';
    char *parr = mstr;
    printf("%6s\n",mstr);
    return mstr;
}

int main(void) {
    // your code goes here
    struct ether_addr ue;
    ue.ether_addr_octet[0] = 255;
    ue.ether_addr_octet[1] = 255;
    ue.ether_addr_octet[2] = 255;
    ue.ether_addr_octet[3] = 255;
    ue.ether_addr_octet[4] = 255;
    ue.ether_addr_octet[5] = 255;
    char *s = ntoa(ue);
    printf("%s",s);
    return 0;
}

【讨论】:

    【解决方案6】:

    Gisway 给出了最好的答案,无论如何对我来说......添加额外的东西

    ...

    #include<netinet/in.h>
    #include<errno.h>
    #include<netdb.h>
    #include<stdio.h>   //For standard things
    #include<stdlib.h>  //malloc
    #include<string.h>  //strlen
    #include<netinet/tcp.h> //Provides declarations for tcp header
    #include<netinet/ip.h>  //Provides declarations for ip header
    #include<netinet/if_ether.h>    //For ETH_P_ALL
    #include<net/ethernet.h>    //For ether_header
    #include<sys/socket.h>
    #include<arpa/inet.h>
    #include<sys/ioctl.h>
    #include<sys/time.h>
    #include<sys/types.h>
    #include<unistd.h>
    
    int main()
    {
    
        int saddr_size , data_size;
        struct sockaddr saddr;
            
        unsigned char *buffer = (unsigned char *) malloc(65536); //Its Big!
        
        printf("Starting...\n");
        
        int sock_raw = socket( AF_PACKET , SOCK_RAW , htons(ETH_P_ALL)) ;
        setsockopt(sock_raw , SOL_SOCKET , SO_BINDTODEVICE , ifce , strlen(ifce)+ 1 );
        
        if(sock_raw < 0)
        {
            //Print the error with proper message
            perror("Socket Error");
            return 1;
        }
        while(1)
        {
            saddr_size = sizeof saddr;
            //Receive a packet
            data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &saddr , (socklen_t*)&saddr_size);
            if(data_size <0 )
            {
                printf("Recvfrom error , failed to get packets\n");
                return 1;
            }
            //Now process the packet
            ProcessPacket(buffer , data_size);
        }
        close(sock_raw);
        printf("Finished");
        return 0;
    }
    
    
    void ProcessPacket(buffer , data_size)
    {
        struct ethhdr *eth = (struct ethhdr *)Buffer;
        
        char src_mac[19];
        sprintf(src_mac, "%02x:%02x:%02x:%02x:%02x:%02x",eth->h_source[0] , eth->h_source[1] , eth->h_source[2] , eth->h_source[3] , eth->h_source[4] , eth->h_source[5]);
        printf("Mac address: %s\n",src_mac);
    }
    

    【讨论】:

      【解决方案7】:

      循环调用sprintf() ^_^:

      #include <stdio.h>
      
      int array[6] = {0x00, 0x0d, 0x3f, 0xcd, 0x02, 0x5f};
      
      void macaddress_str(int a[], char *buf)
      {
          int i;
          for (i = 0; i < 5; i++, buf += 3)
              sprintf(buf, "%02X:", a[i]);
          sprintf(buf, "%02X", a[i]);
      }
      
      int main()
      {
          char buf[100];
          macaddress_str(array, buf);
          printf("%s\n", buf);
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-07-26
        • 2013-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-14
        • 1970-01-01
        相关资源
        最近更新 更多