筆試題目“檢測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范圍內,都不會通過。

 

相信有更好的解決方法,求共勉之。。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM