(华为OJ)C 语言—识别有效的IP地址和掩码并进行分类统计

题目要求(c语言解答):
(华为OJ)C 语言—识别有效的IP地址和掩码并进行分类统计_第1张图片
(华为OJ)C 语言—识别有效的IP地址和掩码并进行分类统计_第2张图片
1、输入多行
2、判断、分类
这里用了链表来存储数据,还可以用二维数组存储,看个人编程习惯,首先找出错误掩码,再去分类IP,顺便找出错误IP
详细思路见代码备注
代码如下:

/************************************************************************
*      文件名:IPclass
*      文件功能描述:识别有效的IP地址和掩码并进行分类统计
*      文件作者名:Mr_han QQ:785937095
*      说明:
*       1、多行字符串。每行一个IP地址和掩码,已~隔开
*       2、请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类
**************************************************************************/
#include 
#include 
#include 

#define LONG long
#define CHAR char
#define N    40
#define M    20

LONG A, B, C, D, E, F, G;

/*定义一个结构体,用来存放IP和掩码*/
typedef struct node{
    CHAR IP[N];
    struct node *next;
}LINK;

/*创建一个链表节点*/
LINK *link_create()
{
    LINK *node = ( LINK * ) malloc ( sizeof(LINK) );
	node->next = NULL;
    return node;
}

/*插入数据 (头插法)*/
void link_insert ( LINK *h, CHAR buf[] )
{
	LINK *node = ( LINK * ) malloc ( sizeof(LINK) );
	strcpy ( node->IP, buf );

	node->next = h->next;
	h->next = node;

    return;
}

//打印(遍历链表)
void link_show(LINK *h)
{
	 while(h->next!=NULL)
	 {
	 	//打印h的下一个节点的数据域
		puts(h->next->IP);
		//指针下移一个节点
		h=h->next;
	 }
}

/*判断IP和mask是否合法,并进行分类*/
void Judge ( CHAR ip[], CHAR mask[] )
{
    /*子网掩码只有这几种可能,若不是则为非法的*/
    if ( strcmp ( mask, "255.0.0.0" ) && strcmp ( mask, "255.255.0.0" ) && strcmp ( mask, "255.255.255.0" ) && strcmp ( mask, "255.255.255.255" ) )
    {
        F++;
        return;
    }
    LONG i = 0, j = 0, k = 0;
    CHAR temp[M] = "";
    LONG num[5]  = {0};                      /*为了存放拆成的四段数据*/
    strcat ( ip, "." );                      /*为方便后面的拆分,在ip数组后面追加个.*/

    while ( '\0' != ip[i] )
    {
        for ( j = 0; '.' != ip[i]; j++,i++ )
        {
            temp[j] = ip[i];                 /*以每个. 为分隔符将IP拆成四段*/
        }
        temp[j] = '\0';
        if ( '.' == ip[i+1] )                /*判断两个.之间是否有数据,没有则为非法*/
        {
            F++;
            return;
        }

        num[k++] = atol(temp);               /*依次放入数组中*/
        if ( k >= 1 )                        /*检查二三四段数据,判断是否0~255之间*/
        {
            if ( num[k] < 0 || num[k] > 255 )
            {
                F++;
                return;
            }
        }
        i++;
    }

    if( 0 < num[0] && 127 > num[0] )         /*根据第一段数据进行分类*/
    {
        A++;
        if ( 10 == num[0] )
        {
            G++;
        }
        return;
    }else if ( 127 < num[0] && 192 > num[0] )
    {
        B++;
        if ( 172 == num[0] && 15 < num[1] && 32 > num[1] )
        {
            G++;
        }
        return;
    }else if ( 191 < num[0] && 224 > num[0] )
    {
        C++;
        if ( 192 == num[0] && 168 == num[1] )
        {
            G++;
        }
        return;
    }else if ( 223 < num[0] && 240 > num[0] )
    {
        D++;
        return;
    }else if ( 239 < num[0] && 256 > num[0] )
    {
        E++;
        return;
    }else if ( 255 < num[0] )
    {
        F++;
    }


    return;
}

/*将每一行拆为IP和mask*/
void Part ( LINK *h )
{
    LONG i, j;
    CHAR ip[M] = "";
    CHAR mask[M] = "";
    while ( h->next != NULL )
    {
        i = j = 0;
        h = h->next;
        while ( '~' != *(h->IP + i) )   /*以~为分隔符*/
        {
            ip[i] = *(h->IP + i);       /*将~以前的字符串放入数组ip中*/
            i++;
        }
        ip[i] = '\0';
        i++;
        while ( '\0' != *(h->IP + i) )  /*将~以后的字符串放入数组mask中*/
        {
            mask[j] = *(h->IP + i);
            i++;j++;
        }
        mask[j] = '\0';

        Judge ( ip, mask );             /*将每个节点的数据依次判断*/
    }
    printf ( "%d %d %d %d %d %d %d", A, B, C, D, E, F, G );

    return;
}

void main()
{
    A = B = C = D = E = F = G = 0;
    LINK *h = link_create();              /*创建一个链表头节点*/
    CHAR buf[N] = "";
    CHAR c;
    printf ( "请输入IP地址和掩码并用~隔开,一次回车换行继续输入,两次回车结束输入:\n" );
    while( ( c = getchar() ) != '\n' )    /*判断是否为回车键,用来确定是否还要继续输入*/
    {
        buf[0] = c;                       /*因第一个字符给了c,所以赋值buf[0]*/
        gets( (buf + 1) );
        link_insert ( h, buf );           /*将数据放入链表*/
    }

    Part ( h );                           /*将每个节点中的IP和mask拆分*/
    return;
}

你可能感兴趣的:(c语言)