user-0 提问: 随意输入一个字符串，判断其是否为IP地址。

回复:
user: user-1
content: 引用 21 楼 jdqsummer 的回复:各有各的想法很厉害，但是小小的功能何必做的怎么复杂 首先要明白楼主需求，知道输入输出格式 我倒觉得符合需求而且代码简洁的程序才是好程序 工作也是这样，不要把小小的功能写了几百行代码感觉很了不起，那些写了几行代码就能实现的才是大神。 其实楼上多种解法都是有效的，我更倾向于21L的意见。要看LZ想干什么了，需求决定实现。我猜LZ应该是学习用的。学习的时候，我一般喜欢简单容易看懂的代码。而一般编程我都假定用户有一定常识，比如不会输入a.b.c.3这样的“IP”。以上只是我的一点看法，解题答案在其他楼层。

user: user-2
content: 引用 19 楼 xusiwei1236 的回复:[quote=引用 12 楼 FancyMouse 的回复:] [quote=引用 11 楼 xusiwei1236 的回复:] if应该是不等于  int isipv4str(const char *str) { 	int i, a[4]; 	if( sscanf(str, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) != 4 ) 		return 0; 	for(i=0; i<4; i++) if (a[i] < 0 || a[i] > 255) return 0; 	return 1; }  str="1.1.1.1.1"就能弄挂[/quote] 这个测试数据很好！应该说“错了”，不能说“弄挂”（程序崩溃才能叫挂）  @zhao4zhong1赵老师格式串最后加的"%c"能解决了这个问题，但是不应该判断它的值，而应该是： if( sscanf(str, "%d.%d.%d.%d%c", &a[0], &a[1], &a[2], &a[3], &end) != 4 ) 这样%c的作用就是：判断a[3]后面有没有字符  附测试代码：  #include <stdio.h>  int isipv4str(const char *str) {     int i, a[4]; 	char end;     if( sscanf(str, "%d.%d.%d.%d%c", &a[0], &a[1], &a[2], &a[3], &end) != 4 )         return 0;     for(i=0; i<4; i++) if (a[i] < 0 || a[i] > 255) return 0;     return 1; }  #define TEST_V4STR(ipstr) printf("isipv4str(\"%s\") : %s\n", ipstr, isipv4str(ipstr) ? "true" : "false")  int main() { 	TEST_V4STR("1.1.1.1"); 	TEST_V4STR("1.1.1.1.1"); 	TEST_V4STR("1.1.1.1.1.1"); 	TEST_V4STR("127.0.0.1"); 	TEST_V4STR("255.255.255.255"); 	TEST_V4STR("255.255.255.256"); 	TEST_V4STR("255.255.255.-1"); 	TEST_V4STR("this.is.a.string");  	return 0; }  [/quote] 弱弱地问一下，你这是“随意输入一个字符串”吗？

user: user-3
content: IPv4的js方式  function checkIpAddress(strIpAddress) 	{ 		var scount=0;  		var ip = strIpAddress;  		var iplength = ip.length;  		var Letters = "1234567890.";  		for (i=0; i < ip.length; i++)    		{     			var CheckChar = ip.charAt(i);     			if (Letters.indexOf(CheckChar) == -1)     			{  	    		//alert ("IP地址格式不对!!，只能输入数字和“.”,格式为XXX.XXX.XXX.XXX 例如：192.168.0.1");   	    		return false;     			}    		}   		for (var i = 0;i<iplength;i++)    			(ip.substr(i,1)==".")?scount++:scount;  		if(scount!=3)  		{    			//alert ("IP地址格式不对!，只能输入数字和“.”,格式为XXX.XXX.XXX.XXX 例如：192.168.0.1");  	 		return false;  		}   		var first = ip.indexOf(".");  		var last = ip.lastIndexOf(".");  		var str1 = ip.substring(0,first);  		var subip = ip.substring(0,last);  		var sublength = subip.length;  		var second = subip.lastIndexOf(".");  		var str2 = subip.substring(first+1,second);  		var str3 = subip.substring(second+1,sublength);  		var str4 = ip.substring(last+1,iplength);   		if (str1=="" || str2=="" ||str3== "" ||str4 == "")  		{ 			//alert("数字不能为空！格式为XXX.XXX.XXX.XXX 例如：192.168.0.1");  			return false;  		}  		 		if (str1< 0 || str1 >255)  		{ 			//alert ("数字范围为0~255！");  		    return false;  		}  		else if (str2< 0 || str2 >255)  		{ 			//alert ("数字范围为0~255！");  			return false;  		}  		else if (str3< 0 || str3 >255)  		{ 			//alert ("数字范围为0~255！");  			return false;  		}  		else if (str4< 0 || str4 >255)  		{ 			//alert ("数字范围为0~255！");  			return false;  		} 		return true; 	}

user: user-4
content: 想多了，用inet_aton然后看返回值就行。

user: user-5
content: 引用 12 楼 FancyMouse 的回复:[quote=引用 11 楼 xusiwei1236 的回复:] if应该是不等于  int isipv4str(const char *str) { 	int i, a[4]; 	if( sscanf(str, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) != 4 ) 		return 0; 	for(i=0; i<4; i++) if (a[i] < 0 || a[i] > 255) return 0; 	return 1; }  str="1.1.1.1.1"就能弄挂[/quote] 这个测试数据很好！应该说“错了”，不能说“弄挂”（程序崩溃才能叫挂）  @zhao4zhong1赵老师格式串最后加的"%c"能解决了这个问题，但是不应该判断它的值，而应该是： if( sscanf(str, "%d.%d.%d.%d%c", &a[0], &a[1], &a[2], &a[3], &end) != 4 ) 这样%c的作用就是：判断a[3]后面有没有字符  附测试代码：  #include <stdio.h>  int isipv4str(const char *str) {     int i, a[4]; 	char end;     if( sscanf(str, "%d.%d.%d.%d%c", &a[0], &a[1], &a[2], &a[3], &end) != 4 )         return 0;     for(i=0; i<4; i++) if (a[i] < 0 || a[i] > 255) return 0;     return 1; }  #define TEST_V4STR(ipstr) printf("isipv4str(\"%s\") : %s\n", ipstr, isipv4str(ipstr) ? "true" : "false")  int main() { 	TEST_V4STR("1.1.1.1"); 	TEST_V4STR("1.1.1.1.1"); 	TEST_V4STR("1.1.1.1.1.1"); 	TEST_V4STR("127.0.0.1"); 	TEST_V4STR("255.255.255.255"); 	TEST_V4STR("255.255.255.256"); 	TEST_V4STR("255.255.255.-1"); 	TEST_V4STR("this.is.a.string");  	return 0; }

user: user-6
content: 各有各的想法很厉害，但是小小的功能何必做的怎么复杂 首先要明白楼主需求，知道输入输出格式 我倒觉得符合需求而且代码简洁的程序才是好程序 工作也是这样，不要把小小的功能写了几百行代码感觉很了不起，那些写了几行代码就能实现的才是大神。

user: user-7
content: 已经有很多大案了！！

user: user-8
content: grep正则表达式规范 在sed、awk及C语言中用正则表达式

user: user-8
content: 用正则表达式匹配字符串是否为IP地址的C代码：  /*Filename:	regex_in_c.c  *Brife:	use c function to use regex  *Author:	One fish  *Date:		2014.8.12 Tuesday  */ #include <sys/types.h> #include <regex.h> #include <stdio.h> #include <stdlib.h>   int main(void) { 	regex_t		reg; 	char		regex[] = "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"; 	char		str[] = "172.168.13.1"; 	size_t		nmatch = 1; 	regmatch_t	pmatch[1]; 	char		errbuf[100]; 	int		i, re;  	//Compile regex to reg	 	re	= regcomp(®, regex, REG_EXTENDED | REG_NEWLINE); 	if ( 0 != re ) { 		regerror(re, ®, errbuf, 100); 		printf("%s\n", errbuf); 		exit(1); 	}  	//Use reg which compiled from pattern to match substring in whole string str 	re	= regexec(®, str, nmatch, pmatch, 0); 	if (REG_NOMATCH == re) { 		printf("No match\n"); 		exit(1); 	} else if (0 == re) { 		printf("matched:\n"); 		for (i = pmatch[0].rm_so; i < pmatch[0].rm_eo; ++i) { 			putchar(str[i]); 		} 		printf("\n"); 		printf("%d, %d\n", pmatch[0].rm_so, pmatch[0].rm_eo); 	}  	//Free ® used in recomp 	regfree(®); 	return 0; } 编译并执行程序：  gcc  -o  regex_in_c  regex_in_c.c  ./regex_in_c  matched:  172.168.13.1  0,12  当在regcomp函数中的cflags参数中指定REG_NOSUB时nmatch和pmatch参数将会被忽略，不能再将它们的值输出来。

user: user-9
content: inet_addr不行吗？

user: user-10
content: 用inet_aton看返回值做判断 不要用inet_addr，具体参见手册

user: user-11
content: 引用 11 楼 xusiwei1236 的回复:if应该是不等于  int isipv4str(const char *str) { 	int i, a[4]; 	if( sscanf(str, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) != 4 ) 		return 0; 	for(i=0; i<4; i++) if (a[i] < 0 || a[i] > 255) return 0; 	return 1; }  str="1.1.1.1.1"就能弄挂

user: user-5
content: if应该是不等于  int isipv4str(const char *str) { 	int i, a[4]; 	if( sscanf(str, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) != 4 ) 		return 0; 	for(i=0; i<4; i++) if (a[i] < 0 || a[i] > 255) return 0; 	return 1; }

user: user-5
content: 忘了，这才是当时写的（记得不止两行）  int isipv4str(const char *str) { 	int i, a[4]; 	if( sscanf(str, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) == 4 ) 		return 0; 	for(i=0; i<4; i++) if (a[i] < 0 || a[i] > 255) return 0; 	return 1; }

user: user-5
content: 我被人面过这题，我的解法：  bool isipv4str(const char *str) { 	int a[4]; 	return sscanf(str, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) == 4; }

user: user-12
content: 引用 17 楼 zhao4zhong1 的回复:#include <stdio.h> int main() {     int IP[4];     int i;     char c;      printf("请输入一个ip地址:");fflush(stdout);     while (1) {         rewind(stdin);         if (5==scanf("%d.%d.%d.%d%c",&IP[0],&IP[1],&IP[2],&IP[3],&c)) {             if (0<=IP[0] && IP[0]<=255              && 0<=IP[1] && IP[1]<=255              && 0<=IP[2] && IP[2]<=255              && 0<=IP[3] && IP[3]<=255              && '\n'==c) {                 break;             } else printf("输入的ip地址格式不对!\n请重新输入:\n");         } else printf("输入的ip地址格式不对!\n请重新输入:\n");     }     for (i=0;i<4;i++) {         printf("IP[%d]=%d\n",i,IP[i]);     }     return 0; }  //IPv6地址表示 //IPv6地址为128位长，但通常写作8组，每组为四个十六进制数的形式。例如： //FE80:0000:0000:0000:AAAA:0000:00C2:0002 是一个合法的IPv6地址。 //要是嫌这个地址看起来还是太长，这里还有种办法来缩减其长度，叫做零压缩法。 //如果几个连续段位的值都是0，那么这些0就可以简单的以::来表示，上述地址就可以写成 //FE80::AAAA:0000:00C2:0002。这里要注意的是只能简化连续的段位的0，其前后的0都要保留， //比如FE80的最后的这个0，不能被简化。还有这个只能用一次，在上例中的 //AAAA后面的0000就不能再次简化。当然也可以在AAAA后面使用::，这样的话前面的 //12个0就不能压缩了。这个限制的目的是为了能准确还原被压缩的0.不然就无法确定每个::代表了多少个0. //2001:0DB8:0000:0000:0000:0000:1428:0000 //2001:0DB8:0000:0000:0000::1428:0000 //2001:0DB8:0:0:0:0:1428:0000 //2001:0DB8:0::0:0:1428:0000 //2001:0DB8::1428:0000都是合法的地址，并且他们是等价的。但 //2001:0DB8::1428::是非法的。（因为这样会使得搞不清楚每个压缩中有几个全零的分组） //同时前导的零可以省略，因此： //2001:0DB8:02de::0e13等价于2001:DB8:2de::e13 #include <stdio.h> #include <string.h> char ipv60[]="2001:0DB8:0000:0000:0000:0000:1428:0000"; char ipv61[]="1040::1"; char ipv62[]="fe80::20c:29ff:fe6b:2516"; char ipv63[]="::ffff:c0a8:5909"; unsigned char ip_v6[16]; void show(char *a) {     int i;     printf("%-39s=>",a);     for (i=0;i<16;i++) printf("%02x ",ip_v6[i]);     printf("\n"); } void inet_addr6(char *a) {     char *p;     int n,i,r,k,j;     short s;     k=0;     p=a;     while (1) {         if (*p==':') k++;         p++;         if (*p==0) break;     }     if (a[0]==':') k--;     i=0;     p=a;     while (1) {         r=sscanf(p,"%hx%n",&s,&n);         if (1==r) {             ip_v6[i]=*((unsigned char *)&s+1);             ip_v6[i+1]=*((unsigned char *)(&s));             i+=2;             if (i>=16) break;             p+=n;         } else if (0==r) {             if (p[0]==':') {                 if (p[1]==':') {                     for (j=0;j<(8-k)*2;j++) ip_v6[i+j]=0;                     i+=(8-k)*2;                     if (i>=16) break;                     p+=2;                 } else {                     p++;                 }             } else {                 printf("Format Error [%s]!\n",a);             }         } else break;     } } int main() {     inet_addr6(ipv60);show(ipv60);     inet_addr6(ipv61);show(ipv61);     inet_addr6(ipv62);show(ipv62);     inet_addr6(ipv63);show(ipv63);     return 0; } //2001:0DB8:0000:0000:0000:0000:1428:0000=>20 01 0d b8 00 00 00 00 00 00 00 00 14 28 00 00 //1040::1                                =>10 40 00 00 00 00 00 00 00 00 00 00 00 00 00 01 //fe80::20c:29ff:fe6b:2516               =>fe 80 00 00 00 00 00 00 02 0c 29 ff fe 6b 25 16 //::ffff:c0a8:5909                       =>00 00 00 00 00 00 00 00 00 00 ff ff c0 a8 59 09 // +1

user: user-2
content: #include <stdio.h> int main() {     int IP[4];     int i;     char c;      printf("请输入一个ip地址:");fflush(stdout);     while (1) {         rewind(stdin);         if (5==scanf("%d.%d.%d.%d%c",&IP[0],&IP[1],&IP[2],&IP[3],&c)) {             if (0<=IP[0] && IP[0]<=255              && 0<=IP[1] && IP[1]<=255              && 0<=IP[2] && IP[2]<=255              && 0<=IP[3] && IP[3]<=255              && '\n'==c) {                 break;             } else printf("输入的ip地址格式不对!\n请重新输入:\n");         } else printf("输入的ip地址格式不对!\n请重新输入:\n");     }     for (i=0;i<4;i++) {         printf("IP[%d]=%d\n",i,IP[i]);     }     return 0; }  //IPv6地址表示 //IPv6地址为128位长，但通常写作8组，每组为四个十六进制数的形式。例如： //FE80:0000:0000:0000:AAAA:0000:00C2:0002 是一个合法的IPv6地址。 //要是嫌这个地址看起来还是太长，这里还有种办法来缩减其长度，叫做零压缩法。 //如果几个连续段位的值都是0，那么这些0就可以简单的以::来表示，上述地址就可以写成 //FE80::AAAA:0000:00C2:0002。这里要注意的是只能简化连续的段位的0，其前后的0都要保留， //比如FE80的最后的这个0，不能被简化。还有这个只能用一次，在上例中的 //AAAA后面的0000就不能再次简化。当然也可以在AAAA后面使用::，这样的话前面的 //12个0就不能压缩了。这个限制的目的是为了能准确还原被压缩的0.不然就无法确定每个::代表了多少个0. //2001:0DB8:0000:0000:0000:0000:1428:0000 //2001:0DB8:0000:0000:0000::1428:0000 //2001:0DB8:0:0:0:0:1428:0000 //2001:0DB8:0::0:0:1428:0000 //2001:0DB8::1428:0000都是合法的地址，并且他们是等价的。但 //2001:0DB8::1428::是非法的。（因为这样会使得搞不清楚每个压缩中有几个全零的分组） //同时前导的零可以省略，因此： //2001:0DB8:02de::0e13等价于2001:DB8:2de::e13 #include <stdio.h> #include <string.h> char ipv60[]="2001:0DB8:0000:0000:0000:0000:1428:0000"; char ipv61[]="1040::1"; char ipv62[]="fe80::20c:29ff:fe6b:2516"; char ipv63[]="::ffff:c0a8:5909"; unsigned char ip_v6[16]; void show(char *a) {     int i;     printf("%-39s=>",a);     for (i=0;i<16;i++) printf("%02x ",ip_v6[i]);     printf("\n"); } void inet_addr6(char *a) {     char *p;     int n,i,r,k,j;     short s;     k=0;     p=a;     while (1) {         if (*p==':') k++;         p++;         if (*p==0) break;     }     if (a[0]==':') k--;     i=0;     p=a;     while (1) {         r=sscanf(p,"%hx%n",&s,&n);         if (1==r) {             ip_v6[i]=*((unsigned char *)&s+1);             ip_v6[i+1]=*((unsigned char *)(&s));             i+=2;             if (i>=16) break;             p+=n;         } else if (0==r) {             if (p[0]==':') {                 if (p[1]==':') {                     for (j=0;j<(8-k)*2;j++) ip_v6[i+j]=0;                     i+=(8-k)*2;                     if (i>=16) break;                     p+=2;                 } else {                     p++;                 }             } else {                 printf("Format Error [%s]!\n",a);             }         } else break;     } } int main() {     inet_addr6(ipv60);show(ipv60);     inet_addr6(ipv61);show(ipv61);     inet_addr6(ipv62);show(ipv62);     inet_addr6(ipv63);show(ipv63);     return 0; } //2001:0DB8:0000:0000:0000:0000:1428:0000=>20 01 0d b8 00 00 00 00 00 00 00 00 14 28 00 00 //1040::1                                =>10 40 00 00 00 00 00 00 00 00 00 00 00 00 00 01 //fe80::20c:29ff:fe6b:2516               =>fe 80 00 00 00 00 00 00 02 0c 29 ff fe 6b 25 16 //::ffff:c0a8:5909                       =>00 00 00 00 00 00 00 00 00 00 ff ff c0 a8 59 09 //

user: user-13
content: 首先你要定义ip地址

user: user-14
content: 獲益良多

user: user-15
content: 楼主，你先要搞清楚什么是正确的ip地址才行哦 192.068.0x1.1是正确的ip地址么？