题目:输入一个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. C++函数指针和类成员函数指针

    一.函数指针——基本形式 char Fun(int n) { return char(n); } //char(*pFun)(int); void main() { char(*pFun)(int); ...

  2. Java获取系统默认浏览器打开链接

    package com.ylx.test; public class DesktopBrowers { public static void main(String[] args) { // 判断当前 ...

  3. Java进阶02 异常处理(转载)

    异常处理 Java的异常处理机制很大一部分来自C++.它允许程序员跳过暂时无法处理的问题,以继续后续的开发,或者让程序根据异常做出更加聪明的处理. Java使用一些特殊的对象来代表异常状况,这样对象称 ...

  4. Python 字典初始化dict()和{}

    参考:https://doughellmann.com/blog/2012/11/12/the-performance-impact-of-using-dict-instead-of-in-cpyth ...

  5. 第二百零一节,jQuery EasyUI,Accordion(分类)组件

    jQuery EasyUI,Accordion(分类)组件 学习要点: 1.加载方式 2.容器属性 3.事件列表 4.方法列表 5.面板属性 本节课重点了解 EasyUI 中 Accordion(选项 ...

  6. linux下Java运行时so文件的附加

    将路径加入至 etc/ld.so.conf 中

  7. SQL2008删除大量数据

    常见问题:工作中数据库难免产生大量的日志,而用户可能关心的只有最近一个月左右的,这些日志占用了服务器磁盘,还可能影响了服务运行效率.甚至在数据库迁移时更因为体积而带来巨大麻烦. 那么,在需要时,删除不 ...

  8. HDU1712ACboy needs your help【分组背包】

    ACboy needs your help Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  9. Python HTMLTestRunner报告及BeautifulReport报告

    import unittest import HTMLTestRunner class Testfunc(unittest.TestCase): def testa(self): "&quo ...

  10. 【转】C#操作word定位光标

    十一.上下左右移动光标位 private void moveLeft() { object moveUnit = Microsoft.Office.Interop.Word.WdUnits.wdWor ...