身份证号码升位(拷贝构造函数+复合类)

本文介绍了如何在C++中定义日期类CDate,用于存储和验证日期,以及学生ID类CStudentID,包含身份证号码的验证功能,包括出生日期和校验码的计算。
摘要由CSDN通过智能技术生成

 题目描述:

class CDate

{

private:

int year, month, day;

public:

CDate(int,int,int);

bool check(); //检验日期是否合法

bool isLeap();

void print();

};

class CStudentID

{

private:

char *p_id, *p_name; //身份证号码,姓名

CDate birthday; //出生日期

int registered; //登记否

public:

CStudentID(char *p_idval, char *p_nameval, CDate &day); //构造函数,若:日期非法;日期与id日期不符;id有非法字符;id不是15位或18位;id是18位但检验码不对,则输出"illegal id"并置registered=0。否则输出对象的属性并置registered=1.

CStudentID(const CId &r); //拷贝构造函数,若r.p_id为15位则升到18位(加年份的19和校验位)

bool checked() { return registered; }

~CStudentId();

};

按上述方式定义一个日期类CDate和学生ID类CStudentID。

身份证第18位校验码的生成方法:

1、将身份证号码前17位数分别乘以7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2。然后将其相加

2、将17位数字和系数乘加的和除以11,得到余数。

3、余数与校验码的对应关系为1,0,X,9,8,7,6,5,4,3,2。也即:如果余数是3,身份证第18位就是9。如果余数是2,身份证的最后一位号码就是X。

主函数:

//输入测试次数t

//循环t次

//每次循环中首先输入年月日,并定义日期对象

//然后输入姓名和身份证号码,并先用构造函数定义一个CStudentID对象s,若s.checked()为true,则再用s拷贝构造s_copy对象

输入

测试数据的组数 t

第一个出生日期年月日

第一个姓名,身份证号码

第二个出生日期年月日

第二个姓名,身份证号码

......

输出

第一个CStudent对象s的信息

第一个拷贝构造CStudent对象s_copy输出的信息或者无输出

第二个CStudent对象s的信息

第二个拷贝构造CStudent对象s_copy输出的信息或者无输出

......

输入样例:

6
2018 2 29
张三 440301180229113
1997 4 30
李四 440301980808554
1920 5 8
王五 530102200508011
1980 1 1
赵六 340524198001010012
1988 11 12
钱七 1102038811120A4
1964 11 15
孙八 432831641115081

输出样例:

张三 illegal id
李四 illegal id
王五 1920年5月8日 530102200508011
王五 1920年5月8日 53010219200508011X
赵六 illegal id
钱七 illegal id
孙八 1964年11月15日 432831641115081
孙八 1964年11月15日 432831196411150810

该题需要注意析构函数题干打错,以及拷贝构造函数需要改成CStudentID才能正确执行,不能原封照抄代码框架

AC代码:

#include <iostream>
#include <cstring>
using namespace std;

class CDate {
	private:
		int year, month, day;
	public:
		CDate(int y, int m, int d) {
			year = y;
			month = m;
			day = d;
		}
		int gy() {
			return year;
		}
		int gm() {
			return month;
		}
		int gd() {
			return day;
		}
		bool check() {
			if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
				if (day > 31) {
					return false;
				}
			}
			if (month == 4 || month == 6 || month == 9 || month == 11) {
				if (day > 30) {
					return false;
				}
			}
			if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
				if (month == 2 && day > 29) {
					return false;
				}
			} else {
				if (month == 2 && day > 28) {
					return false;
				}
			}
			return true;
		} //检验日期是否合法
		bool isLeap();
		void print();

};

class CStudentID {
	private:

		char *p_id, *p_name; //身份证号码,姓名

		CDate birthday; //出生日期

		int registered; //登记否

	public:
		~CStudentID() {
			if (p_name != NULL) {
				delete[]p_name;
			}
			if (p_id != NULL) {
				delete[]p_id;
			}
		}
		bool datelegal() {
			if ((*(p_id + 6) - '0') * 1000 + (*(p_id + 7) - '0') * 100 + (*(p_id + 8) - '0') * 10 + (*
			        (p_id + 9) - '0') == birthday.gy()
			        && (*(p_id + 10) - '0') * 10 + (*(p_id + 11) - '0') == birthday.gm()
			        && (*(p_id + 12) - '0') * 10 + (*(p_id + 13) - '0') == birthday.gd() && strlen(p_id) == 18) {
				return true;
			} else if ((*(p_id + 6) - '0') * 10 + * (p_id + 7) - '0' == birthday.gy() % 100
			           && (*(p_id + 8) - '0') * 10 + (*(p_id + 9) - '0') == birthday.gm()
			           && ( (*(p_id + 10) - '0') * 10 + (*(p_id + 11) - '0') == birthday.gd() )
			           && ( strlen(p_id) == 15) ) {
				return true;
			} else {
				return false;
			}
		}
		bool legalword() {
			if (strlen(p_id) == 15) {
				for (int i = 0; i < 15; i++) {
					if (*(p_id + i) < '0' || *(p_id + i) > '9') {
						return false;
					}
				}
				return true;
			} else if (strlen(p_id) == 18) {
				for (int i = 0; i < 18; i++) {
					if (*(p_id + i) < '0' || *(p_id + i) > '9') {
						return false;
					}
				}
				return true;
			} else {
				return false;
			}
		}
		bool checked() {
			return registered;
		}
		char checkcode() {
			int a[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
			int sum = 0;
			for (int i = 0; i < 17; i++) {
				sum = sum + (*(p_id + i) - '0') * a[i];
			}
			sum = sum % 11;
			char b[11] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
			char res = b[sum];
			return res;
		}

		CStudentID(char *p_idval, char *p_nameval,
		           CDate &day): birthday(
			               day) { //构造函数,若:日期非法;日期与id日期不符;id有非法字符;id不是15位或18位;id是18位但检验码不对,则输出"illegal id"并置registered=0。否则输出对象的属性并置registered=1.
			p_id = new char[strlen(p_idval) + 1];
			strcpy(p_id, p_idval);
			p_name = new char[strlen(p_nameval) + 1];
			strcpy(p_name, p_nameval);
			if (datelegal() && legalword() && birthday.check()) {
				if (strlen(p_id) == 18) {

					if (*(p_id + 17) == checkcode()) {
						cout << p_name << " " << birthday.gy() << "年" << birthday.gm() << "月" << birthday.gd() << "日";
						cout << " " << p_id << endl;
						registered = 1;
					} else {
						cout << p_name << " " << "illegal id" << endl;
						registered = 0;
					}
				} else {
					cout << p_name << " " << birthday.gy() << "年" << birthday.gm() << "月" << birthday.gd() << "日";
					cout << " " << p_id << endl;
					registered = 1;
				}
			} else {
				cout << p_name << " " << "illegal id" << endl;
				registered = 0;
			}

		}
		CStudentID(CStudentID &r): birthday(r.birthday) {
			int i;
			p_name = new char[strlen(r.p_name) + 1];
			strcpy(p_name, r.p_name);
			p_id = new char[strlen(r.p_id) + 4];
			for (i = 0; i < 6; i++) {
				*(p_id + i) = *(r.p_id + i);
			}
			*(p_id + 6) = birthday.gy() / 1000 + '0';
			*(p_id + 7) = birthday.gy() / 100 % 10 + '0';
			for (i = 8; i < 17; i++) {
				*(p_id + i) = *(r.p_id + i - 2);
			}
			*(p_id + 17) = checkcode();
			*(p_id + 18) = '\0';
			cout << p_name << " " << birthday.gy() << "年" << birthday.gm() << "月" << birthday.gd() << "日" ;
			cout << " " << p_id << endl;

		}
		//拷贝构造函数,若r.p_id为15位则升到18位(加年份的19和校验位)
};

int main() {
	int t, y, m, d;
	char name[10];
	char sfz[20];
	cin >> t;
	while (t--) {
		cin >> y >> m >> d;
		CDate obj(y, m, d);
		cin >> name >> sfz;
		CStudentID obj1(sfz, name, obj);
		if (obj1.checked() == 1 && strlen(sfz) == 15) {
			CStudentID obj2(obj1);
		}
	}
}

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shiroha Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值