题目详情
编写程序,将十进制点分的IP转换为32位二进制IP地址。程序要能验证输入的十进制点分IP地址的合法性。用户输入的IP不和法时,输出"data error"。
请使用模块化程序设计的思想,将功能模块编写成函数。通过指针传递参数,操作数据,返回结果。在主函数中输入IP地址,调用函数进行合法性验证和转换,在主函数中输出32位二进制IP。
输入格式:
十进制点分IP地址(英文句点)
输出格式:
32位二进制数(二进制字符串)
输入样例:
202.151.96.33
输出样例:
11001010100101110110000000100001
提示:十进制转换为二进制。对整数部分,除2取余,直到商为0。例如13/2=6…1(低位)6/2=3…03/2=1…11/2=0…1转换后的二进制数位1101
我解题所使用的库工具(库函数)
strtok函数(头文件为string.h)
作用是 分解字符串为一组组字符串
函数原型char *strtok(char s[], const char *delim);
也就是修改s这个传入的字符串,然后把s中是delim这个字符的字符变为’\0’
使用: 第一次传入s后,返回值是指向s修改后的第一段, 后面再使用strtok只需传入NULL和delim, 将会默认再次返回上次已经修改的s的第二段。
atoi(表示 ascii to integer)(头文件stdlib.h)
作用是 把字符串转换成整型数的一个函数
函数原型:nt atoi(const char *nptr);
注意:如果不能转换成int或者需要转化的字符串为空串的话,返回的是0
个人思路
一开始只想着检验ip地址中各段数字的范围为0~255, 没想到没A过(多半是ip合法性检验的点没A过了)==…
后面接连搞了差不多两天(因为要上课(ノ・ω・)ノ)。最后使用了strtok和atoi函数A过了。
因为题目需要对合法性验证和转换做对应的函数分别处理,所以我分别定义了legal(负责合法性验证和存储各段数字字符串)、transform(负责转换的功能) 。
所以大致解题思路为以下步骤:
-
先整体读入字符串
-
调用legal函数做合法性验证及存储各段数字字符串
①先遍历一遍检查头尾是否出现’.',中间是否重复出现’.'。以及中间出现了既不是数字字符,也不是’.'的字符
②后面使用strtok来进行切割分段处理,处理的过程使用atoi函数将各段数字字符串转换为相对应的整数(整数需要判断是否在0~255之间)。也要注意是否已经读入了四段数字字符串,如果超过四段或者不够四段都说明此ip非法。ps:其实这里可以顺便进行转换功能,从而一套直接完成,但是题目要求需要单独的转换函数。 -
合法性验证完成后,后面分别将四段数字字符串分别以字符指针的形式传入transform函数,后面在主函数分别输出已经修改好的各段二进制数(字符串)即可。
-
我的测试数据如下
//202.151.96.33
//111.111.11.111.11
//1.1.1.1.
//1.1..1.1
//.1.1.1.1
//1.*1.1.1
- 下面代码
#include <iostream>
#include <cstring>
#include <stdlib.h>
using namespace std;
int main()
{
void legal(char *p, char (*p1)[9]);
void transform(char *p);
char ip[100], digit[5][9]={'\0'}; //输入最多为15个字符,所以需要16个char元素;temp用来处理转化后的四段数字字符串(第1.第2.第3.第4)
cin.getline(ip,100);
legal(ip,digit); //进行合法性验证 顺便进行存储各段数字字符串
//到了这一步说明ip是合法的
for(int i=0;i<4;i++)
{
transform(digit[i]); //进行转换
cout<<digit[i];
}
return 0;
}
//合法ip 应是四段数字,且各段数字的范围为0~255, 各段数字以'.'分隔
void legal(char *p, char (*p1)[9])
{
int tmp,i=0,error=0,j;
char *temp;
if(p[0]=='.') error=1; //判断字符串最前面是否有'.'
for(j=0;p[j]!='\0';j++)
{
if( (p[j]<48||p[j]>57)&&p[j]!='.' ){ //检查1是否有如'*'等不合法的字符
error=1;
break;
}
if(p[j]=='.'){ //判断是否重复出现'.'
if(p[j+1]=='.'){
error=1;
break;
}
}
}
if(p[j-1]=='.') error=1; //判断最后面1有没有'.'
temp=strtok(p,"."); //开始切割存储工作
while(temp!=NULL){
//j=3; //来控制各段数字的存储位置
strcpy(p1[i],temp);
tmp=atoi(p1[i]);
if(tmp<0||tmp>255||i>3){
error=1;
break;
}
i++;
temp=strtok(NULL,".");
}
if(i<4||error){
cout<<"data error";
exit(0);
}
}
void transform(char *p)
{
int j=7, tmp=atoi(p); //j来控制各段数字的存储位置
while(j>=0){
p[j]=tmp%2+48;
tmp=tmp/2;
j--;
}
p[8]='\0';
return ;
}