Ich bereite mich auf ein Quiz vor und habe den starken Verdacht, dass ich mit der Implementierung einer solchen Funktion beauftragt werden könnte. Wie können wir bei einer gegebenen IP-Adresse in Netzwerkschreibweise diese aus einer 32-Bit-Ganzzahl in eine Zeichenfolge in punktierter Dezimalschreibweise umwandeln (so etwas wie 155.247.182.83) …? Offensichtlich können wir auch keine Art von Inet-Funktionen verwenden … Ich bin ratlos!
Ganzzahl zu IP-Adresse – C
Kris Richards
Rose Perrone
Du eigentlich kann Verwenden Sie eine Inet-Funktion. Beobachten.
Haupt c:
#include <arpa/inet.h>
main() {
uint32_t ip = 2110443574;
struct in_addr ip_addr;
ip_addr.s_addr = ip;
printf("The IP address is %s\n", inet_ntoa(ip_addr));
}
Die ergebnisse von gcc main.c -ansi; ./a.out
ist
Die IP-Adresse lautet 54.208.202.125
Beachten Sie, dass ein Kommentator sagte, dass dies unter Windows nicht funktioniert.
Wernsee
Hier ist eine einfache Methode, dies zu tun: Die (ip >> 8)
, (ip >> 16)
und (ip >> 24)
verschiebt das 2., 3. und 4. Byte in das niederwertige Byte, während die & 0xFF
isoliert das niedrigstwertige Byte bei jedem Schritt.
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]);
}
Es gibt eine implizite bytes[0] = (ip >> 0) & 0xFF;
im ersten Schritt.
Verwenden snprintf()
um es in eine Zeichenfolge zu drucken.
Ein anderer Ansatz:
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);
Yuval Adam
Hinweis: Brechen Sie die 32-Bit-Ganzzahl in 4 8-Bit-Ganzzahlen auf und drucken Sie sie aus.
Etwas in der Art (nicht kompiliert, YMMV):
int i = 0xDEADBEEF; // some 32-bit integer
printf("%i.%i.%i.%i",
(i >> 24) & 0xFF,
(i >> 16) & 0xFF,
(i >> 8) & 0xFF,
i & 0xFF);
Dies ist, was ich tun würde, wenn ich einen String-Puffer zum Füllen übergeben würde und ich wüsste, dass der Puffer groß genug ist (dh mindestens 16 Zeichen lang):
sprintf(buffer, "%d.%d.%d.%d",
(ip >> 24) & 0xFF,
(ip >> 16) & 0xFF,
(ip >> 8) & 0xFF,
(ip ) & 0xFF);
Dies wäre etwas schneller, als zuerst ein Byte-Array zu erstellen, und ich denke, es ist besser lesbar. Normalerweise würde ich snprintf verwenden, aber IP-Adressen dürfen nicht mehr als 16 Zeichen lang sein, einschließlich der abschließenden Null.
Alternativ, wenn ich nach einer Funktion gefragt wurde, die ein Zeichen zurückgibt *:
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;
}
Stysel
#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);
}
Gemeinschaft
Von string nach int und zurück
const char * s_ip = "192.168.0.5";
unsigned int ip;
unsigned char * c_ip = (unsigned char *)&ip;
sscanf(s_ip, "%hhu.%hhu.%hhu.%hhu", &c_ip[3], &c_ip[2], &c_ip[1], &c_ip[0]);
printf("%u.%u.%u.%u", ((ip & 0xff000000) >> 24), ((ip & 0x00ff0000) >> 16), ((ip & 0x0000ff00) >> 8), (ip & 0x000000ff));
%hhu weist sscanf an, in unsigned char-Zeiger einzulesen; (Lesen von small int mit scanf)
inet_ntoa von glibc
char *
inet_ntoa (struct in_addr in)
{
unsigned char *bytes = (unsigned char *) ∈
__snprintf (buffer, sizeof (buffer), "%d.%d.%d.%d",
bytes[0], bytes[1], bytes[2], bytes[3]);
return buffer;
}
Wenn Sie Code schreiben – sollten Sie Inet-Funktionen verwenden – und wenn ich den Test geben würde, würde ich Sie durchfallen lassen, weil Sie funktionierenden getesteten Code neu erfunden haben 🙂
– mmmmmm
5. November 2009 um 12:52 Uhr
@Mark Wenn Sie Windows verwenden, können Sie sich nicht auf die Inet-Funktionen verlassen … Sie haben es irgendwie geschafft, sie so in die Winsock-Bibliothek einzubinden
inet_ntoa
das nur grundlegendes Bit-Twiddling ausführen soll, kann fehlschlagen.– notbad.jpeg
29. April 2015 um 20:58 Uhr