很久以前写了一个《C语言身份证信息查询系统》,如果你点击链接进去看了。
估计也会被我那磅礴大气的代码震惊到的,最近复习/学习文件操作,把代码改了改,算是对以前还不会文件操作的时候的愿望,哈哈
写代码时思路倒是挺清晰的,不过连写带改错也弄了一下午。应该没有什么错误了(如果您有兴趣测试,欢迎反馈错误信息)
代码是在Linux下写的,不知道在win下是否报错。而且感觉自己好菜啊啊啊,本以为几十行代码搞定的东西,足足用了150多行。就这样吧。废话不多说,上原理和代码
看下程序执行:
身份证验证是否非法的判断原理:
一. 将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
二. 将这17位数字和系数相乘的结果相加。
三. 用加出来和除以11,看余数是多少?
四. 余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 2。
五. 通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。
例如:某男性的身份证号码是34052419800101001X。我们要看看这个身份证是不是合法的身份证。
首先:我们得出,前17位的乘积和是189
然后:用189除以11得出的结果是17 + 2/11,也就是说余数是2。
最后:通过对应规则就可以知道余数2对应的数字是x。所以,这是一个合格的身份证号码。
而且,判断性别是根据第17位数字,奇数为男,偶数为女
[c]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define IDLEN 18
#define AREALEN 6
#define BIRTHLEN 8
#define FILEURL “./UserID.txt”
int LegalInput(char p[])
{
	int i;
	printf(“Please input you ID card
>”);
	fgets(p, (sizeof(char)+1)*IDLEN, stdin);
	/* 判断输入数据的长度是否合法 */
	if((strlen(p)-1) != IDLEN) {
		printf(“Error! You need input the ’18’ length ID card
“);
		return EXIT_FAILURE;
	}
	/* 判断输入的前17位是否为数字 */
	for(i = 0; i<IDLEN-1; i++) {
		if(!isdigit(p[i])) {
			printf(“Error! You need input the right num
“);
			return EXIT_FAILURE;
		}
	}
	/* 判断第18位是否为数字或是字符’X|x’*/
	if(!isdigit(p[IDLEN-1]) && (p[IDLEN-1] != ‘x’) && (p[IDLEN-1] != ‘X’)) {
		printf(“Error! You need input the right num
“);
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}
int LegalID(char p[], int q[])
{
	int i, sum, remainder;
	/*将输入的字符转化为数字*/
	for(i = 0; i< IDLEN-1; i++)
		q[i+1] =  p[i] – ‘0’;
	//1,求出前17位和系数相乘的和
	//	对应的系数为 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
	sum = q[1]*7 + q[2]*9 + q[3]*10 + q[4]*5 + q[5]*8 + q[6]*4 + q[7]*2
	       + q[8]*1 + q[9]*6 + q[10]*3 +q[11]*7 + q[12]*9 + q[13]*10
	       + q[14]*5  + q[15]*8 + q[16]*4 + q[17]*2;  
	// 2,求余
	remainder = sum % 11;
	//3,余数只可能有0~10这11个结果
	 //对应的最后一位身份证号码为1 0 X 9 8 7 6 5 4 3 2
	char tmp[12] = {‘1’, ‘0’, ‘x’, ‘9’, ‘8’, ‘7’, ‘6’, ‘5’, ‘4’, ‘3’, ‘2’};
	if(remainder == 2) {
		if(p[IDLEN-1] != ‘x’ && p[IDLEN-1] != ‘X’) {
			printf(“Error! You need input the right num
“);
			return EXIT_FAILURE;
		}
	}
	else {
		if(p[IDLEN-1] != tmp[remainder]) {
			printf(“Error! You need input the right num
“);
			return EXIT_FAILURE;
		}
	}
	return EXIT_SUCCESS;
}
int main(void)
{
	int i, sex;
	char buf[1024], *p1, *p2;
	char userInput_char[IDLEN+1];
	int userInput_int[IDLEN+1]; //从[1]开始使用
	char userInputArea[AREALEN+1];
	char userInputBirth[BIRTHLEN+1];
	char tmp[AREALEN+1];
	char Area[30];
	FILE * fpr;
	/* 打开文件 */
	if((fpr = fopen(FILEURL, “r”)) == NULL)
	{
		printf(“Open file failed.
“);
		return EXIT_FAILURE;
	}
memset(buf, 0, sizeof(buf));
	/* 判断输入是否合法 */
	int ret = -1;
	while(ret != EXIT_SUCCESS) {
		if(LegalInput(userInput_char) == EXIT_SUCCESS)
			ret = LegalID(userInput_char, userInput_int);
	}
	/* 保存前1-6位 地区 */
	for(i = 0; i<AREALEN; i++)
		userInputArea[i] = userInput_char[i];
	/* 保存第7-14为 出生日期 */
	int ii = 0;
	for(i = AREALEN; i<AREALEN+BIRTHLEN; i++)
		userInputBirth[ii++] = userInput_char[i];
	userInputBirth[ii] = 0;
	/* 第17位 代表性别 sex=1 男, sex=0 女*/
	if((userInput_int[17] % 2) == 0)
		sex = 0;
	else
		sex = 1;
	/* 从文件中读取数据 */
	while(fgets(buf, sizeof(buf), fpr) != NULL)
	{
		/* p1指向第一个”:”,p2指向第二个”:” */
		p1 = strstr(buf, “:”);
		p1++;
		p2 = p1+7;
		/* 获得文件中的地区ID */
		for(i = 0; i< AREALEN; i++)
			tmp[i] = p1[i];
		tmp[i] = 0;
		/* 输出所在地 */
		if(strcmp(userInputArea, tmp) == 0) {
			//printf(“%s
“, p2);
			strcpy(Area, p2);
			break;
		}
		/* 清楚内存 */
		memset(buf, 0, sizeof(buf));
	}
	fclose(fpr);
	printf(“出生地:%s”, Area);
	printf(“出生日期:%s
“, userInputBirth);
	if(sex == 1)
		printf(“性别:男
“);
	else
		printf(“性别:女
“);
	return 0;
}
[/c]
数据保存在文件./UserID.txt中,格式如下
:110000:北京市
:110100:北京市市辖区
:110101:北京市东城区
:110102:北京市西城区
:110103:北京市崇文区
:110104:北京市宣武区
:110105:北京市朝阳区
:110106:北京市丰台区
:110107:北京市石景山区
:110108:北京市海淀区
:110109:北京市门头沟区你可以网上去找程式代码,或是使用我的文件:百度网盘(可能不全,测试时发现有没有的地区)


