题目:输入一个IPv4字符串,如“1.2.3.4”,输出对应的无符号整数,如本例输出为 0x01020304。

来源:某500强企业面试题目

思路:从尾部扫描到头部,一旦发现无法转换,立即返回,减少无谓操作。

#include "stdio.h"
#include "stdlib.h"
#include "string.h" bool ConvertIPv4ToUInt(const char *strIP, unsigned int *ip)
{
if (!strIP) {
return false;
} int Len = strlen(strIP); // min len is 7, e.g. 1.2.3.4; max len is 15, e.g. 123.234.121.254
if ((Len < ) || (Len > )) {
return false;
} int num[] = { }; // 4 parts of number
int partNum = ; // 1 part of number
int base = ; // 10^base
int dotCount = ; // dot count // from right to left
for (int i = Len - ; i >= ; --i) {
char ch = strIP[i];
if (ch == '.') {
// if the first char of last char is ".", e.g. ".1.2.3.4" or "1.2.", exit
if ((i == ) || (i == Len - )){
return false;
}
dotCount++; // if more than 3 dot found, e.g. "1.2.3.4.5", exit
if (dotCount > ) {
return false;
} // save partNum to num[]
num[dotCount - ] = partNum;
partNum = ;
base = ;
}
else if ((ch < '') || (ch > '')) {
// if illeagal char inside, exit
return false;
}
else {
// handle digit char
partNum += (ch - '') * base;
base *= ; if (partNum > ) {
return false;
} // handle first part num
if (i == ) {
// if count of "." is not enough, exit
if (dotCount != ) {
return false;
}
num[dotCount] = partNum;
}
}
} // output ip
*ip = ;
for (int i = ; i < ; ++i) {
*ip += num[i] << (i * );
} return true;
} int main(int argc, char* argv[])
{
char* strIP[] = {
"",
"1.2",
"1.2.3",
"111.222.113",
"1.2.3.",
".1.2.3",
"256.1.2.3",
"1.2.3.4",
"1.2.3.4.5",
"12.234.45.6",
"12.2345.45.6",
"1.a.2.3",
"1.2.3.4 ",
"1.2. 3.4",
"1,2,3,4",
}; for (int i = ; i < sizeof(strIP) / sizeof(char *); ++i){
unsigned int ip = ;
if (ConvertIPv4ToUInt(strIP[i], &ip)){
printf("%s -> %08X\n", strIP[i], ip);
}
else {
printf("%s is not valid\n", strIP[i]);
}
} getchar();
return ;
}

输出结果为:

 is not valid
1.2 is not valid
1.2. is not valid
111.222. is not valid
1.2.. is not valid
.1.2. is not valid
256.1.2.3 is not valid
1.2.3.4 ->
1.2.3.4. is not valid
12.234.45.6 -> 0CEA2D06
12.2345.45.6 is not valid
.a.2.3 is not valid
1.2.3.4 is not valid
1.2. 3.4 is not valid
,,, is not valid

从工程化角度考虑,有几点需要注意:

1、输入的字符串是否有效?
    不但要判断输入字符串是否为空,还要在处理过程中随时检查中间结果值,快速返回。
    需要考虑“.”的非法位置,如开头和结尾不能有“.”。
    需要考虑某段数字过长(超过255)。
    需要考虑“.”的个数,必须有且只有3个。

2、快速识别错误并退出
    发现有问题就快速退出,不需要进行无谓的多余计算。

3、考虑到转换失败的情况,所以返回值设定为bool,通过参数指针来返回转换结果。
    如果设定UInt为返回值,则无法通过返回值判断转换是否成功。
    需要的话,可以将bool的返回值改为enum,从而返回各种错误类型供调用者使用。

从编程角度考虑,有几点需要注意:

1、从后向前扫描字符串时,需要注意处理顺序。
    先判断字符是否为“.”,然后判断是否为非数字,剩下的就是数字了。
    这样的顺序逻辑清晰,便于在发现问题时快速退出。

2、对于类似问题,可以将测试集先列出来,写代码时候就可以有的放矢的进行容错处理了。

[笔记]一道C语言面试题:IPv4字符串转为UInt整数的更多相关文章

  1. [笔记]一道C语言面试题:大整数乘法

    题目:输入两个数字字符串,如“1234567890”和“987654321”,返回二者相乘的结果字符串,如本例返回为“1219326311126352690”. 来源:某500强企业面试题目 思路:从 ...

  2. 一道C语言面试题:得到整数的M进制表示字符串

    题目:输入整数n和M,输出n在M进制下的表示字符串.如n=3000,M=16,输出16进制下3000的表示字符串,为“BB8” 来源:某500强企业面试题目 思路:对n取模M,将得到的数字压入栈中,再 ...

  3. [Python学习笔记1]Python语言基础 数学运算符 字符串 列表

    这个系列是我在学习Python语言的过程中记录的笔记,主要是一些知识点汇总,而非学习教程,可供有一定编程基础者参考.文中偏见和不足难以避免,仅供参考,欢迎批评指正. 本系列笔记主要参考文献是官网文档: ...

  4. 一道C语言面试题:判断字串是否可以通过重新排列字母使之对称

    题目:输入一个字符串,如“adcaeceeed”,判断是否可以通过重新排列使之可以输出对称字符串,如本例可以输出“adceeeecda”,返回True. 来源:某500强企业面试题目 思路:扫描字串, ...

  5. C语言面试题分类->字符串处理

    1.strlen:计算字符串长度(不包含'\0') 实现想法:遍历字符串,直到'\0'结束 #include<stdio.h> #include<stdlib.h> #incl ...

  6. 一道C语言面试题:写一个宏,将16位的整数转为Big Endian

    题目:输入16位整数x,如0x1234,将其转为Big Endian格式再输出,此例为输出 0x3412 来源:某500强企业面试题目 思路:将x左移8位得到a,将x右移8位得到b,a+b即为所得 / ...

  7. 【R笔记】R语言中的字符串处理函数

    内容概览 尽管R是一门以数值向量和矩阵为核心的统计语言,但字符串同样极为重要.从医疗研究数据里的出生日期到文本挖掘的应用,字符串数据在R程序中使用的频率非常高.R语言提供了很多字符串操作函数,本文仅简 ...

  8. C语言面试题大汇总之华为面试题 Eddy整理

    1.局部变量能否和全局变量重名? 答:能,局部会屏蔽全局.要用全局变量,需要使用"::" ;局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局 ...

  9. 12个有趣的C语言面试题

    摘要:12个C语言面试题,涉及指针.进程.运算.结构体.函数.内存,看看你能做出几个! 1.gets()函数 问:请找出下面代码里的问题: #include<stdio.h> int ma ...

随机推荐

  1. WCF信道工厂Channel Factory

    ChannelFactory<TChannel> 类 一个创建不同类型通道的工厂,客户端使用这些通道将消息发送到不同配置的服务终结点. 命名空间: System.ServiceModel ...

  2. python3 读取csv的常用语法

    import csv #打开文件,用with打开可以不用去特意关闭file了,python3不支持file()打开文件,只能用open() with open("info.csv" ...

  3. Photoshop脚本之获得文件夹下所有特定后缀文件

    function getAllFiles(folderName,houzhui){ folderName var regthis = new RegExp( '.+\.('+houzhui+')$', ...

  4. with root cause 解决办法

    现象:1.工程在启动的时候无异常,当页面加载到包含spring:message标签的页面时,在后台报空指针异常,同时控制               台会显示with root cause提示: 2. ...

  5. python 自动化之路 day 19 Django基础[二]

    Django - 路由系统 url.py - 视图函数 views.py - 数据库操作 models.py - 模板引擎渲染 - HttpReponse(字符串) - render(request, ...

  6. Gmail 邮件配置备忘

    1.smtp端口号不是默认的25,smtp的是587 2.必须设置“允许使用不够安全的应用” 其他的按照网上文档设置就好了

  7. Android桌面小组件的使用

    一:建立一个类继承AppWidgetProvider 二:建立AWP的布局文件: 布局自己定义一个,但是在使用控件上是有要求的: 以上是Widget目前支持的控件. 三:编写AWP的信息文件:需要在r ...

  8. [Spring MVC]学习笔记--@RequestMapping

    @RequestMapping是用来将请求的url,映射到整个类,或者里面的方法. @Controller @RequestMapping("/test") public clas ...

  9. 《从零开始学Swift》学习笔记(Day 14)——字符串的插入、删除和替换

    原创文章,欢迎转载.转载请注明:关东升的博客 对应可变字符串可以插入.删除和替换,String提供了几个方法可以帮助实现这些操作.这些方法如下: splice(_:atIndex:).在索引位置插入字 ...

  10. isnull在order by中的使用——让我长见识了

    select * from VisitLogorder by ISNULL(NextVisitDate,'2299-01-01') 此sql的作用是查找表中的数据,并按照NextVisitDate字段 ...