zoukankan      html  css  js  c++  java
  • 笔试题目“检测IPv4地址”的实现

    网友的力量是强大的,昨天发了一篇Post,关于一道面试/笔试题。得到网友们的众多解决方法。我不得不承认自己写的代码是如此的烂。尽管如此,也是很有必要和大家一起来探讨,也有必要写出自己心中所想。这样才有进步,才有改变,才能将自己的烂代码优化。接着发一段烂代码,希望学习网友们更加优美,优秀的代码。

    笔试题目

    判断一个字符串是否是IPv4地址。如果是返回ture,否则返回false。同样不可以使用库函数。可以选择用C/C++,C#或者Java。

    e.g.  C/C++:  bool checkIPv4(char * ip){}

    解决方法

    鄙人是这样想的,按照‘.’先将每个字串分割出来。如“192.168.203.70”分割为192,168,203,70四个整型。然后再判断这四个整型的范围,是否在0~255之间。我总觉得这种考虑欠妥,应该选择类似正则表达式那样的方法吧。但是不会写。。。

    一开始我是这样写的。

    检查IPv4
    #include <stdio.h>
    
    bool checkIpv4(char * ip)
    {
        char *p=ip;
        char *q=ip;
        char *c;
        int i=0,s,count=0;
        if(*p=='.') //处理特殊情况
            return false;
        while(*p!='\0')
        {
            if(*p=='.'||*(p+1)=='\0')   //根据'.'将字符串切割出来
            {
                count++;            //计算切割的字串个数
                if(*(p+1)=='\0')    //处理最后一个字串
                {
                    i++;
                    q=p;
                }
                else
                    q=p-1;
    
                s=0;
                for(int j=1;j<=i;j++)   //将切割出来的字串变成整型
                {
                    int x=*q-'0';       //字符减'0'变为整型
                    for(int k=1;k<j;k++)
                        x*=10;
                    s+=x;
                    q--;
                }
    
                printf("%d\n",s);
                if(s<0||s>255)      //判断切割出来的字串是否在ipv4范围内
                    return false;
                i=0;
            }
            else
            {
                i++;
            }
            p++;
        }
        if(count==4)
            return true;
        else
            return false;
    }
    
    int main(void)
    {
        char ip[]="a.v.0.0";
        if(checkIpv4(ip))
            printf("该地址是IPv4地址\n");
        else
            printf("该地址不是IPv4地址\n");
        return 0;
    }

    但是很明显是有问题的。

    当检验“192.168.203.70”的时候,结果是可以的。

    但是当检验的对象不是数字的时候,例如“a.168.203.70”,居然也可以验证通过,欠考虑了。

    所以在切割出来的每个整型,我再检查了一遍每个整型是否在0~9范围内,不是的话返回false。

     if(x<0||x>9)        //判断x是否在0~9之间
          return false;

    感谢网友zdd的提醒,确实没有考虑到类型“1...3”出现连续点的情况。果然自己写的东西够烂的。我是这样处理的:

    出现这样的情况是因为

                s=0;
    
                for(int j=1;j<=i;j++)   //将切割出来的字串变成整型
                {
                    int x=*q-'0';       //字符减'0'变为整型
                    if(x<0||x>9)        //判断x是否在0~9之间
                        return false;
    
                    for(int k=1;k<j;k++)    //第几位乘以几-1个10.
                        x*=10;
                    s+=x;
                    q--;
                }

    里面的for循环会发生不执行的情况,所以就不处理类似“1...3”出现连续点的情况了。我改变代码如下

                s=0;
                int x=-1;
                for(int j=1;j<=i;j++)   //将切割出来的字串变成整型
                {
                    x=*q-'0';       //字符减'0'变为整型
                    if(x<0||x>9)        //判断x是否在0~9之间
                        return false;
    
                    for(int k=1;k<j;k++)    //第几位乘以几-1个10.
                        x*=10;
                    s+=x;
                    q--;
                }
    
                if(x==-1)
                    return false;//防止类型“1...3”出现连续点的情况

    将x放在for循环外面,用来检测是否出现连续个点的情况。

    下面是完整的代码

     

    #include <stdio.h>
    
    bool checkIpv4(char * ip)
    {
        printf("检验对象是:%s\n",ip);
        char *p=ip;     //遍历指针
        char *q=ip;     //字串指针
        int i=0,s,count=0;  //i是每个字串的长度,s是字串转化为的整型,count是字串的个数
    
        if(*p=='.') //处理特殊情况
            return false;
    
        while(*p!='\0') //遍历每个字符
        {
            if(*p=='.'||*(p+1)=='\0')   //根据'.'将字符串切割出来,最后一个字串根据'\0'识别
            {
                count++;            //计算切割的字串个数
    
                if(*(p+1)=='\0')    //处理最后一个字串,‘\0’识别的时候
                {
                    i++;
                    q=p;
                }
                else
                    q=p-1;  //‘.切割’
    
                s=0;
                int x=-1;
                for(int j=1;j<=i;j++)   //将切割出来的字串变成整型
                {
                    x=*q-'0';       //字符减'0'变为整型
                    if(x<0||x>9)        //判断x是否在0~9之间
                        return false;
    
                    for(int k=1;k<j;k++)    //第几位乘以几-1个10.
                        x*=10;
                    s+=x;
                    q--;
                }
    
                if(x==-1)
                    return false;//防止类型“1...3”出现连续点的情况
    
                printf("%d\n",s);
                if(s<0||s>255)      //判断切割出来的字串是否在ipv4范围内
                    return false;
                i=0;
            }
            else
            {
                i++;
            }
            p++;
        }
        if(count==4)    //检查是否是四个字串
            return true;
        else
            return false;
    }
    
    int main(void)
    {
        char ip[]="1..2.3";
        if(checkIpv4(ip))
            printf("该地址是IPv4地址\n");
        else
            printf("该地址不是IPv4地址\n");
        return 0;
    }

     

     

    解释应该挺清楚的了。这个时候只要切割出来的字符不在0~9范围内,都不会通过。

    相信有更好的解决方法,求共勉之。。。。
  • 相关阅读:
    linux定时任务之crontab
    Examples of GoF Design Patterns--摘录
    weblogic升级之ddconverter
    Memcached分布式算法详解--转
    java实现迷宫算法--转
    kmp java implement--转
    2013年小结及2014年展望
    深入redis内部--字典实现
    项目管理学习笔记之二.工作分解
    android在当前app该文件下创建一个文件夹
  • 原文地址:https://www.cnblogs.com/rond/p/2507408.html
Copyright © 2011-2022 走看看