身份证号码生成(公测).测试BUG
程序代码:
main.c 文件 #include #include #include #include #include #include #define DATA struct data #define AREA struct area #define INF information //information: 用户信息 AREA * Ap[31]; //定义全局指针数组变量 void sequenceCode(DATA *INF, char identifier[]); void sexNumber(DATA *INF, char identifier[]); void label(AREA * head); AREA * provinceAndCity(); AREA * province(); int verifyCode(char identifier[]); void anewIdentifier(DATA * INF, char bak[], FILE * fp); struct data { char name[16]; char sex[4]; char birthday[9]; AREA * number; }; struct area { int code; char address[56]; struct area * next; }; void openFile(AREA * head, AREA * Ap[]) { int proving; FILE * fp; AREA * p, * q; p = head; if ((fp = fopen("areaData.dat", "r")) == NULL) { printf("地区数据加载失败,程序退出!"); getch(); exit(-1); } while (feof(fp) == 0) { if ((q = (AREA *)malloc(sizeof(AREA))) == NULL) { printf("内存不足!程序退出!"); getch(); exit(-1); } proving = fscanf(fp, "%d %s", &q->code, q->address); //如果正确输入 则返回2 if (proving < 2) //判断是否正确输入 { free(q); //释放未成功输入信息的空间 q = NULL; break; } label(q); p->next = q; p = p->next; } fclose(fp); p->next = NULL; printf("数据加载成功!\n"); } int _information(DATA *INF, char identifier[]) //用户信息录入 { int n; printf("输入姓名:"); gets(INF->name); puts("0. 女性"); puts("1. 男性"); printf("选择性别:"); scanf("%d", &n); switch(n) { case 0: strcpy(INF->sex, "女"); break; case 1: strcpy(INF->sex, "男"); break; default : printf("输入错误!"); return -1; } fflush(stdin); //清空键盘输入流,防前面scanf的回车 printf("输入出生日期:"); gets(INF->birthday); printf("\n"); puts("0. 直辖市!"); puts("1. 其他省份!"); printf("选择省市:"); scanf("%d", &n); switch(n) { case 0: INF->number = provinceAndCity(); break; //连接直辖市 地址码 并返回该地址码在内存位置地址 case 1: INF->number = province(); break; //连接省份 地址码 并返回该地址码在内存位置地址 default : printf("输入错误!"); return -1; } itoa(INF->number->code , identifier, 10); //将整形(int)转换为字符串型存到身份证数组内 strcat(identifier, INF->birthday); //把生日信息连接到身份证数组后 return 0; } int saveFile(DATA * INF, char identifier[]) //把屏幕信息保存到文件内 { FILE * fp; if ((fp = fopen("saveInformation.txt", "w")) == NULL) return 1; fprintf(fp, "性别:%s \n姓名: %s \n出生日期: %s\n身份证号码: %s\n地址:%s \n", INF->sex, INF->name, INF->birthday, identifier, INF->number->address); fputs("--------------------------------------------------------------------------\n", fp); fclose(fp); return 0; } int main(void) { int r, m; char n[2]=""; char identifier[19]; char bak[19]; FILE * fp; AREA head; DATA INF; head.next = NULL; openFile(&head, Ap); //加载地区码 if (_information(&INF, identifier) == -1) //用户信息录入 { printf("输入异常,程序退出!"); getch(); exit(0); } strcpy(bak, identifier); //存储一个备份,等再次生成使用 srand((unsigned)time(NULL)); //让rand()每次随机出来的数不一样的 初始条件 sequenceCode(&INF, identifier); //生成顺序码前两位数 sexNumber(&INF, identifier); //生成性别码 n[0] = verifyCode(identifier); //生成校验码 strcat(identifier, n); //把校验码存到身份证号最后一位 system( "cls "); //清屏! printf("性别:%s\n", INF.sex); printf("姓名:%s\n", INF.name); printf("出生日期:%s\n", INF.birthday); printf("身份证号码:%s\n", identifier); printf("地址:%s\n", INF.number->address); r = saveFile(&INF, identifier); //把屏幕信息保存到文件内 if (r == 0) printf("以上信息以成功保存到saveInformation.txt内!\n"); else system("del saveInformation.txt"); if ((fp = fopen("saveInformation.txt", "a")) == NULL) //以最加形式打开文件 return 0; while(1) { printf("输入'0'再次生成编号!"); if(getch() == '0') anewIdentifier(&INF, bak, fp); else break; } fclose(fp); //province(); //for(i=0; i<31; i++) // printf("%s %s\n", Ap[i]->code, Ap[i]->address); //provinceAndCity(); return 0; }chooseArea.c 文件 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #define DATA struct data #define AREA struct area extern AREA * Ap[31]; extern struct area //声明area 已经在其他源文件中已经声明 { int code; char address[56]; struct area * next; }; extern struct data //同上 { char name[16]; char sex[4]; char birthday[9]; AREA * number; }; void label(AREA * head) //记录第一个直辖市 或 省份 的地址 { AREA * p; static int i=0; p = head; if (p->code % 10000 == 0) { Ap[i] = p; //printf("%d.\t%s\n", i, Ap[i]->address); i++; } } void sequenceCode(DATA *INF, char identifier[]) //生成顺序码前两位数 { int i; char temp[4]; //srand((unsigned)time(NULL)); i = rand() % 100; //随机出一个数 itoa(i, temp, 10); //转换成字符串储存在temp数组内 if (i <= 9) { strcat(identifier, "0"); //如果随机出现的数小于9,在身份证数组内连接一个字符0 strcat(identifier, temp); //连接随机数 } else strcat(identifier, temp); } void sexNumber(DATA *INF, char identifier[]) //生成性别码 { int i; char temp[4]; //srand((unsigned)time(NULL)); i = rand() % 10; if (strcmp(INF->sex, "女") == 0) { while(i % 2 != 0) //让随机函数随机出一个偶数 i = rand() % 10; itoa(i, temp, 10); strcat(identifier, temp); } else if(strcmp(INF->sex, "男") == 0) { while(i % 2 == 0) //让随机函数随机出一个奇数 i = rand() % 10; itoa(i, temp, 10); strcat(identifier, temp); } } AREA * provinceAndCity() { int j, n, m; AREA * p, * temp[50]; printf("0.\t%s\n", Ap[0]->address); printf("1.\t%s\n", Ap[1]->address); printf("2.\t%s\n", Ap[8]->address); printf("3.\t%s\n", Ap[21]->address); printf("输入你城市编号:"); scanf("%d", &n); switch(n) { case 0: m = 0; break; case 1: m = 1; break; case 2: m = 8; break; case 3: m = 21; break; } p = Ap[m]; j = 0; while (p->code != Ap[m+1]->code) { printf("%d.\t%s\n", j, p->address); //输出该阶段的的区县 temp[j] = p; //并把该段区县地址存的内存地址存到temp指针数组内 j++; p = p->next; } printf("输入你区县编号:"); scanf("%d", &n); printf("%s\n", temp[n]->address); return temp[n]; } AREA * province() { int i, j, n, m; AREA * p, * temp[60], * temp_2[30]; for(i=2; i<8; i++) printf("%d.\t%s\n", i-2, Ap[i]->address); for(i=9; i<21; i++) printf("%d.\t%s\n", i-3, Ap[i]->address); for(i=22; i<31; i++) printf("%d.\t%s\n", i-4, Ap[i]->address); printf("输入你省份编号:"); scanf("%d", &n); if (n < 8) n += 2; else if (n < 21) n += 3; else n += 4; p = Ap[n]; j = 0; while (p != Ap[n+1]) { if (p->code % 100 == 0) { printf("%d.\t%s\n", j, p->address); temp[j] = p; j++; } p = p->next; } printf("输入你城市编号:"); scanf("%d", &m); p = temp[m]; j = 0; while (p!= temp[m+1] && p!= Ap[n+1]) { printf("%d.\t%s\n", j, p->address); temp_2[j] = p; j++; p = p->next; } printf("输入你区县编号:"); scanf("%d", &n); printf("%s\n", temp_2[n]->address); return temp_2[n]; } int verifyCode(char identifier[]) { int i, n, m, y[17],sum=0; int t[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; char temp[19]; strcpy(temp, identifier); for (i=0; temp[i] != '\0'; i++) //把字符型的数字-'0'=就等于该数字字符的阿拉伯数字 y[i] = temp[i] - '0'; for (i=0; temp[i] != '\0'; i++) //将身份证号码前17位数分别乘以不同的系数,系数即是数组t[18] t[i] *= y[i]; for (i=0; temp[i] != '\0'; i++) //将得到的17个乘积相加。 sum += t[i]; n = sum % 11; //将相加后的和除以11并得到余数 switch(n) //余数可能为0 1 2 3 4 5 6 7 8 9 10这些个数字,其对应的身份证最后一位校验码为1 0 X 9 8 7 6 5 4 3 2。 { case 0: m = 1; break; case 1: m = 0; break; case 2: m = 72; break; case 3: m = 9; break; case 4: m = 8; break; case 5: m = 7; break; case 6: m = 6; break; case 7: m = 5; break; case 8: m = 4; break; case 9: m = 3; break; case 10: m = 2; break; } return m+'0'; //还原回字符 } void anewIdentifier(DATA * INF, char bak[], FILE * fp) { char temp[19]; char n[2]=""; strcpy(temp, bak); sequenceCode(INF, temp); sexNumber(INF, temp); //生成性别码 n[0] = verifyCode(temp); //生成校验码 strcat(temp, n); //把校验码存到身份证号最后一位 printf("身份证号码:%s\n", temp); fputs(temp, fp); fputs("\n", fp); fflush(fp); return; }
这个工程由两个文件组成..
分别保存为main.c和chooseArea.c
用vc++6.0 添加这两个文件即可使用;;
望发现BUG把发到hz453@内.