C++ 身份证设定(复合类+拷贝构造)

题目描述
定义一个身份证类PID,包含私有属性:身份证类型、身份证号码、出生日期;另外包含方法:构造、拷贝构造打印等。
身份证类型表示一代身份证或者二代身份证,分别用1和2表示 身份证号码是一个字符串,长度为15或者18
出生日期是一个类,包含私有属性年、月、日,以及构造函数等(根据需要添加其他方法) 构造函数要注意是复合类,要考虑复合类成员的构造
打印函数把身份证的所有属性都输出,输出格式看示例
拷贝构造作用:如果身份证号码是15位的就升级为18位,包括把身份证类型改为2,然后把号码扩展,规则如下:
1 原15位身份证的第7位到12位表示出生年月日,每个两位;把年份的2位扩展为四位。
2. 把扩展后的17个数字求和,取总和的末尾数字,如果末尾数字是0,则将0改为X,然后把这个数字作为第18。
3.如果身份证号码已经是18位,就无需升级 例如身份证123456910203000,表示91年2月3日出生,然后根据类属性出生日期知道是1991年,不是2091年。因此扩展为12345619910203000
接着把17个数字相加得到46,取末尾6,最终扩展为123456199102030006
输入
第一行输入t表示t个示例
第二行输入一个身份证的5个属性,顺序为:类型、号码、出生年、月、日
依次输入t行

输出
采用拷贝构造函数的方法对身份证号码升级,然后输出

样例输入
3
1 123456910203000 1991 2 3
2 654321200001018889 2000 1 1
1 234567001217000 2000 12 17
样例输出
type=2 birth=1991.02.03
ID=123456199102030006
type=2 birth=2000.01.01
ID=654321200001018889
type=2 birth=2000.12.17
ID=23456720001217000X

#include<iostream>
#include <cstring>
#include<iomanip>
using namespace std;
class Date{
private:
    int year, month, day;
public:
    Date(int y, int m, int d) { year = y; month = m; day = d; }
    void set(int y, int m, int d) { year = y; month = m; day = d; }
    Date(){}
    int getYear() { return year; }
    int getMonth() { return month; }
    int getDay() { return day; }
    void print(){
     cout<<year<<"."<<setfill('0')<<setw(2)<<month<<"."<<setfill('0')<<setw(2)<<day;
 }
};
class PID{
 private:
  int type;
  char *num;
  Date birth;
 public:
  PID(int t,char *n,int y,int m,int d){
   type=t;
   num=new char[strlen(n)+1];
   strcpy(num,n);
   birth.set(y,m,d);
  }
  PID(const PID &p){
   type=2;
   int i,sum=0;
   birth=p.birth;
   num=new char[18];
   if(strlen(p.num)==15){
    for(i=0;i<6;i++)//身份证前六位相同
    *(num+i)=*(p.num+i);
    if(birth.getYear()>1900&&birth.getYear()<2000)//判断15位的身份证年份是1900还是20000
    { *(num+6)='1';  
      *(num+7)='9';
    }
    else
    { *(num+6)='2';  
     *(num+7)='0';
    }
    for(;i<15;i++)
     *(num+i+2)=*(p.num+i);
    for(i=0;i<17;i++){//计算前17位的和,字符型转换为整型需减去ASCII码'0'
     sum=sum+*(num+i)-'0';
    }
    if(sum%10==0)//取余
     *(num+17)='X';
    else
     *(num+17)=sum%10+'0';
   }
   else{
    for(i=0;i<18;i++)
    *(num+i)=*(p.num+i);
   }
   *(num+18)='\0' ; //这步很重要!!!不然输出完身份证号后面会有乱码
  }
  void print(){
   cout<<"type="<<type<<" birth=";
   birth.print();
   cout<<endl<<"ID="<<num<<endl;
  }
  ~PID(){
   if(num!=NULL)
   delete [] num;
  }
  
};
int main(){
 int t,type,y,m,d;
 char num[19];
 cin>>t;
 while(t--){
  cin>>type>>num>>y>>m>>d;
  PID p1(type,num,y,m,d);
  PID p2(p1);
  p2.print();
 }
}

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值