题目描述:
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);
}
}
}