2013-01-06 21 views
7

Tôi gặp sự cố với inet_aton để chuyển đổi địa chỉ mạng. Đoạn code dưới đây hoạt động tốt để chuyển đổi địa chỉ 10.0.0.1inet_aton chuyển đổi 010.000.000.001 sai?

char *x1; 
struct sockaddr_in si_other; 
inet_aton("10.0.0.1", &si_other.sin_addr); 
printf("si_other.sin_addr =%lu\n",si_other.sin_addr); 
x1 = inet_ntoa(si_other.sin_addr); 
printf("x1=%s\n",x1); 

Nó ra:

si_other.sin_addr =16777226 
x1=10.0.0.01 

Không có vấn đề cho đến nay. Tuy nhiên, chức năng công trình kỳ lạ khi 010.000.000.001 được truyền

char *x2; 
struct sockaddr_in si_other2; 
inet_aton("010.000.000.001", &si_other2.sin_addr); 
printf("si_other2.sin_addr =%lu\n",si_other2.sin_addr); 
x2 = inet_ntoa(si_other2.sin_addr); 
printf("x2=%s\n",x2); 

kết quả đầu ra:

si_other.sin_addr2 =16777224 
x2=8.0.0.01 

Chức năng hoạt động tốt khi 192.168.0.1192.168.000.001 được thông qua.

Bất cứ ai có thể giải thích cho tôi vấn đề là gì và cách tôi có thể khắc phục sự cố? (lưu ý: Tôi cần phải chuyển địa chỉ IP dưới dạng 010.000.000.001 vào mã của tôi)

+2

Nếu bạn không thể chuẩn hóa các địa chỉ có dấu thập phân của mình thành ký hiệu chiều rộng biến tiêu chuẩn, bạn sẽ phải viết hàm của chính mình tương đương với 'inet_aton' xử lý chiều rộng cố định không chuẩn Địa chỉ IPv4. Chúc vui vẻ! –

Trả lời

12

0 đứng đầu là interpreted as indicating the number is octal. 010 (oct) == 8 (tháng mười hai). Bạn cần phải sửa đổi đầu vào thành inet_aton để tránh điều này hoặc tự chuyển đổi nó theo một cách khác.

const char *str = "010.000.000.001"; 
inet_aton(str[0] == '0' ? str+1:str, &si_other.sin_addr); 

Là giải pháp đơn giản nhất, nhưng nó sẽ được tốt hơn để sửa chữa bất cứ điều gì (snprintf?) Tạo ra chuỗi ở nơi đầu tiên để tránh sự nhầm lẫn.

(Vì giải pháp này sẽ không hoạt động với một số trường hợp cạnh vẫn còn, bao gồm "001.0.0.1", "0xF.0.0.1", "1" và nhiều địa chỉ IPv4 hợp lệ khác).

Bạn trivially có thể "bình thường hóa" đầu vào của bạn sử dụng sscanf, ngay cả khi bạn không thể kiểm soát như thế nào nó được tạo ra ở nơi đầu tiên (mặc dù đó thực sự nó đã có một lỗi whever nó đến từ quan điểm của tôi):

#include <stdio.h> 
#include <stdlib.h> 

int main() { 
    const char *str="010.020.030.040"; 
    int parts[4]; 
    sscanf(str, "%d.%d.%d.%d", parts+0, parts+1, parts+2, parts+3); 
    char *out = NULL; 
    asprintf(&out, "%d.%d.%d.%d", parts[0], parts[1], parts[2], parts[3]); 
    printf("%s\n", out); 
    free(out); 
    return 0; 
} 
+2

Điều gì sẽ mang lại lợi nhuận trên '010.020.030.040'? Rõ ràng, trường đầu tiên sẽ là '10' (thập phân), nhưng còn những gì khác? –

+0

@JonathanLeffler vẫn không khắc phục được trường hợp đó. – Flexo

+4

Giải pháp đúng sẽ là cắt bỏ số 0 từ tất cả các octet. 1 tuy nhiên. – jweyrich

Các vấn đề liên quan