【问题标题】:Issues changing IP Address from int to string将 IP 地址从 int 更改为 string 的问题
【发布时间】:2016-10-28 22:05:17
【问题描述】:

我正在尝试将 IP 地址(当前为 IPv4,但可识别 IPv6)从 int 数组格式转换为格式化字符串。我正在开发 Ubuntu Linux。

我区分了 IPv4 和 IPv6 地址,然后尝试将 int 数组转换为字符串。

这是我正在使用的代码:

#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>

int main(void)
{
    int i;
    unsigned int val32;
    int ma_ip[4];
    char m_ip[4];
    char ipaddr[INET_ADDRSTRLEN], ipv6[INET6_ADDRSTRLEN];
    int no = 0;
    char *token;
    char s3[] = "10.1.35.1";
    /* just example. test only one ip address.. */
    for(i = 0; i < 1; i++)
    {
        char *mm = strstr(s3, ":");
        if( *mm != NULL)
        {
             token = strtok(s3, ":");
             while(token != NULL)
             {
                 token = strtok(NULL, ":");
                 no++;
             }
             if(no >= 2 && no <= 7)
                 printf("\nthis is ipv6\n");
             else
                 printf("\nwrong ipv6\n");
         }
         else
         {
             token = strtok(s3, ".");
             while(token != NULL)
             {
                 token = strtok(NULL, ".");
                 no++;
             }
             if(no == 4)
             {
                 printf("\nthis is ipv4.\n");
                 val32 = inet_addr(s3)
                 ma_ip[i] = val32;
             }
             else
                 printf("\nwrong ipv4.\n")
         }
         inet_ntop(AF_INET,&ma_ip[0],ipaddr,INET_ADDRSTRLEN);
         printf("\nipaddr = %s\n", ipaddr);
         strcpy(&m_ip[0], ipaddr);
         printf("\nafter strcpy = %s\n", m_ip[0]);
    }
}

这个输出是错误的:

ipaddr = 0.0.0.10

实际上应该是:

ipaddr = 10.1.35.1

我在strcpy 之后的最后一个printf 中也收到此错误:

格式“%s”需要“char *”类型的参数,但参数 2 有“int”类型错误!**

为什么会发生这种情况,我该如何解决?

【问题讨论】:

    标签: c string network-programming ipv6 ipv4


    【解决方案1】:

    m_ip[0] 指向第一个元素的位置。如果您想打印字符串,请尝试使用m_ip 即数组名称或&amp;m_ip[0],它基本上传递了第一个元素的地址,这可以解释为pointer 并基本上导致分段错误。使用m_ip 打印(但仍然只有0.0.0.10)。

    您的程序中的另一点是您应该在strstr 操作之后将mmNULL 进行比较。

    对于网络地址操作,我建议你看看this question

    【讨论】:

    • 我想要更详细的解决方案。谢谢你的回答。
    【解决方案2】:

    我对你的程序有一些疑问。 你是在转换ip字符串吗

     char s3[] = "10.1.35.1";
    

    转成整数再转回字符串??

    我想这就是你需要的

    struct sockaddr_in sa;
    char str[INET_ADDRSTRLEN];
    
    // store this IP address in sa:
    inet_pton(AF_INET, "192.0.2.33", &(sa.sin_addr));
    
    // now get it back and print it
    inet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN);
    
    printf("%s\n", str); // prints "192.0.2.33"
    

    关于strcpy之后的最后一个printf,应该是

    printf("\nafter strcpy = %s\n", m_ip);
    

    【讨论】:

    • 不要使用inet_ptoninet_ntop,最好使用getaddrinfo()getnameinfo()
    【解决方案3】:

    这是一个可行的版本。您的代码的问题是,strtok() 正在修剪字符串's3'。到 n == 4 时,字符串只剩下“10”。

     #include <stdio.h>
     #include <string.h>
     #include <arpa/inet.h>
     #include <malloc.h>
    
    int main(void)
    {
        int i;
        unsigned int val32;
        int ma_ip[4];
        char m_ip[4];
        char ipaddr[INET_ADDRSTRLEN], ipv6[INET6_ADDRSTRLEN];
        int no = 0;
        char *token;
        char s3[] = "10.1.35.1";
        char *s4 = malloc(strlen(s3)+1);   
        strcpy(s4, s3);               //You can save the original string.
        /* just example. test only one ip address.. */
        for(i = 0; i < 1; i++)
        {
            char *mm = strstr(s3, ":");
            if( mm != NULL)
            {
                 token = strtok(s3, ":");
                 while(token != NULL)
                 {
                     token = strtok(NULL, ":");
                     no++;
                 }
                 if(no >= 2 && no <= 7)
                     printf("\nthis is ipv6\n");
                 else
                     printf("\nwrong ipv6\n");
             }
             else
             {
                 token = strtok(s3, ".");
                 while(token != NULL)
                 {
                     token = strtok(NULL, ".");
                     no++;
                 }
                 if(no == 4)
                 {
                     printf("\nthis is ipv4.\n");
                     val32 = inet_addr(s4);  //use the intact string s4, instead of s3.
                     ma_ip[i] = val32;
                 }
                 else
                     printf("\nwrong ipv4.\n");
             }
             inet_ntop(AF_INET,&ma_ip[0],ipaddr,INET_ADDRSTRLEN);
             printf("\nipaddr = %s\n", ipaddr);
             strcpy(&m_ip[0], ipaddr);
             printf("\nafter strcpy = %s\n", m_ip);
        }
    }
    

    【讨论】:

    • strcpy(&amp;m_ip[0], ipaddr); 是非常错误的。不要使用strcpy,使用strncpychar[4] 对于格式化的 IP 地址字符串显然不够大。
    • 是的,你是对的。我刚刚注意到代码的 strtok() 问题,并对其进行了快速更改。没有注意到 strcpy() 问题。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 1970-01-01
    • 2016-11-23
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多