题目:输入一个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. Eclipse没有 web Project 选项的解决办法

    装下插件即可.步骤如下: 选择 Help >Software Updates >Find and Install.这个选项会让您可以下载和安装 Web 工具,且无需转到 Web 站点. 选 ...

  2. linux学习之缓存机制

    linux中的缓存机制 在Linux系统中,为了提高文件系统性能,内核利用一部分物理内存分配出缓冲区,用于缓存系统操作和数据文件,当内核收到读写的请求时,内核先去缓存区找是否有请求的数据,有就直接返回 ...

  3. Mysql备份工具比较

    Mysql备份工具比较 大 | 中 | 小 [ 2012/12/25 12:10 | by Sonic ] 1. 使用automysqlbackup http://sourceforge.net/pr ...

  4. linux. -bash: fork: retry: Resource temporarily unavailable错误

    切换用户或登陆服务器后执行ls命令报错: -bash: fork: retry: Resource temporarily unavailable 上面这段错误提示的本质是Linux操作系统无法创建更 ...

  5. printf不支持%lf

    #include <stdio.h> int square137(int n); void p137() { double x = 3.0; int y = (int)x; printf( ...

  6. SQL数据库查询练习题

    一.            设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher).四个表的结构分别如表1-1的表(一)~表( ...

  7. TPM概述

    TPM(Trusted Platform Module)安全芯片,是指符合TPM(可信赖平台模块)标准的安全芯片.标准由TCG(可信赖计算组织,Trusted Computing Group)提出,目 ...

  8. Trees on the level UVA - 122 复习二叉树建立过程,bfs,queue,strchr,sscanf的使用。

    Trees are fundamental in many branches of computer science (Pun definitely intended). Current state- ...

  9. python 开发技巧(1)-- 用PyCharm安装第三方库

    在python开发中,我们经常需要安装一些python的第三方类库,包等等,用PyCharm就会安装就会超级方便 1.打开上面的小扳手 2.点击页面左边的Project Interpreter 3.点 ...

  10. Redis Scan的使用方式以及Spring redis的坑

    SpringRedisTemplate针对这个Scan进行了封装,示例使用(针对最新库spring-data-redis-1.8.1.RELEASE): Set<Object> execu ...