Целое число к IP-адресу - C

Другая общая версия примера Andrew, страшное двустишие кода

parent.addChild(child);
child.setParent(parent);

Вместо того, чтобы волноваться, делаются ли обе строки всегда вместе и в последовательном порядке, Вы могли бы сделать методы частными и сделать, чтобы друг функционировал для осуществления непротиворечивости:

class Parent;

class Object {
private:
    void setParent(Parent&);

    friend void addChild(Parent& parent, Object& child);
};

class Parent : public Object {
private:
     void addChild(Object& child);

     friend void addChild(Parent& parent, Object& child);
};

void addChild(Parent& parent, Object& child) {
    if( &parent == &child ){ 
        wetPants(); 
    }
    parent.addChild(child);
    child.setParent(parent);
}

, Другими словами, можно сохранить открытые интерфейсы меньшими и осуществить инварианты, которые сокращают через классы и объекты в друге функции.

23
задан Jon Seigel 26 April 2010 в 22:52
поделиться

5 ответов

Вот простой способ сделать это: (ip >> 8) , (ip >> 16) и (ip >> 24) перемещает 2-й, 3-й и 4-й байты в байт младшего порядка, в то время как & 0xFF изолирует младший байт на каждом шаге.

void print_ip(unsigned int ip)
{
    unsigned char bytes[4];
    bytes[0] = ip & 0xFF;
    bytes[1] = (ip >> 8) & 0xFF;
    bytes[2] = (ip >> 16) & 0xFF;
    bytes[3] = (ip >> 24) & 0xFF;   
    printf("%d.%d.%d.%d\n", bytes[3], bytes[2], bytes[1], bytes[0]);        
}

Подразумевается bytes [0] = (ip >> 0) & 0xFF; на первом этапе.

Используйте snprintf () , чтобы вывести его в строку.

62
ответ дан 29 November 2019 в 00:33
поделиться

Другой подход:

union IP {
    unsigned int ip;
    struct {
      unsigned char d;
      unsigned char c;
      unsigned char b;
      unsigned char a;
    } ip2;
};

...
char  ips[20];
IP ip;
ip.ip = 0xAABBCCDD;

sprintf(ips, "%x.%x.%x.%x", ip.ip2.a, ip.ip2.b, ip.ip2.c, ip.ip2.d);
printf("%s\n", ips);
6
ответ дан 29 November 2019 в 00:33
поделиться

Подсказка: разбейте 32-битное целое число на 4 8-битных целых и распечатайте их.

Что-то вроде этого (не скомпилировано, YMMV):

int i = 0xDEADBEEF; // some 32-bit integer
printf("%i.%i.%i.%i",
          (i >> 24) & 0xFF,
          (i >> 16) & 0xFF,
          (i >> 8) & 0xFF,
          i & 0xFF);
5
ответ дан 29 November 2019 в 00:33
поделиться

Это то, что я сделал бы, если бы передал строковый буфер для заполнения, и я знал, что буфер достаточно велик (т.е. не менее 16 символов):

sprintf(buffer, "%d.%d.%d.%d",
  (ip >> 24) & 0xFF,
  (ip >> 16) & 0xFF,
  (ip >>  8) & 0xFF,
  (ip      ) & 0xFF);

Это было бы немного быстрее, чем сначала создать байтовый массив, и я думаю, это более читабельно. Обычно я использую snprintf, но IP-адреса не могут быть длиннее 16 символов, включая завершающий нуль.

В качестве альтернативы, если меня попросили функцию, возвращающую char *:

char* IPAddressToString(int ip)
{
  char[] result = new char[16];

  sprintf(result, "%d.%d.%d.%d",
    (ip >> 24) & 0xFF,
    (ip >> 16) & 0xFF,
    (ip >>  8) & 0xFF,
    (ip      ) & 0xFF);

  return result;
}
1
ответ дан 29 November 2019 в 00:33
поделиться
#include "stdio.h"

void print_ip(int ip) {
   unsigned char bytes[4];
   int i;
   for(i=0; i<4; i++) {
      bytes[i] = (ip >> i*8) & 0xFF;
   }
   printf("%d.%d.%d.%d\n", bytes[3], bytes[2], bytes[1], bytes[0]);
}

int main() {
   int ip = 0xDEADBEEF;
   print_ip(ip);   
}
1
ответ дан 29 November 2019 в 00:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: