C语言设计程序判断身份证号的合法性,并输出到指定日期的天数?

一个真实的身份证号满足以下规则:
身份证号码长度验证:身份证长度为18位,其中前17位全为数字0-9,第18位为0-9或者'X'(大小写皆可)。
身份证号码输入正确性验证:身份证号码第18位为校验码,将前17位各位数字乘以对应加权因子并求和,mod 11得到余数,根据余数通过校验码对照表查得校验码。
加权因子
|位置序号|1 |2 |3 |4 |5 |6 |7 |8 |9 |10|11|12|13|14|15|16|17|
|加权因子|7 |9 |10|5 |8 |4 |2 |1 |6 |3 |7 |9 |10|5 |8 |4 |2 |校验码对照表
|余数 |1 |2 |3 |4 |5 |6 |7 |8 |9 |10|0|
|校验码|0 |X |9 |8 |7 |6 |5 |4 |3 |2 |1|
出生年月验证:身份证号码第7位到第14位为出生年月日,格式为YYYYMMDD,请注意闰年,大小月份,超过目前日期,等特殊情况。
现在给你一个身份证号,请你确认一下这是否满足上述三条规则。如果满足,输出他出生到2019.4.2这一天的天数。
输入 一行字符串
输出 若不符合身份证规则,输出 No ,若符合身份证规则,输出出生到2019.4.2这一天的天数。

天数包括2019.4.2这天吗?

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define THISYEAR   2019
#define THISMONTH  4
#define TODAY      2
#define DATA       20190402
#define MOD        11

const int days[2][12]={
    {31,28,31,30,31,30,31,31,30,31,30,31},
    {31,29,31,30,31,30,31,31,30,31,30,31}
};

const int WF[17] = {
    7, 9, 10, 5, 8, 4, 2, 1, 6,
    3, 7, 9, 10, 5, 8, 4, 2
};

const char PIN[11] = {
    '1', '0', 'X', '9', '8', '7',
    '6', '5', '4', '3', '2'
};


int leapyear(int); //判断闰年
int s2d(char *, int, int);
int countdays(int,int,int);


int main(void) {

  int is_valid = 1; //ID是否合格的标志
  int y,m,d;
  char ID[19];
  scanf("%s", ID);

  if (strlen(ID) != 18) {
    is_valid = 0;
  }
  else {
    for (int i = 0; i < 17; i++) {
      if (!isdigit(ID[i])) {
        is_valid = 0;
        break;
      }
    }

    y = s2d(ID, 6, 9);
    m = s2d(ID, 10, 11);
    d = s2d(ID, 12, 13);
    if (m < 1 || m > 12 || d > 31 || d < 1 ||
        (leapyear(y) && m == 2 && d > 29)||
        10000*y+100*m+d>=DATA)
      is_valid = 0;

    int sum = 0;
    for (int i = 0; i < 17; i++) {
      sum += (ID[i] - '0') * WF[i];
    }
    if (toupper(PIN[sum % MOD]) != toupper(ID[17]))
      is_valid = 0;
  }
  if (is_valid) {
    int totaldays = countdays(y,m,d);
    printf("%d\n",totaldays);
  }
  else
    puts("No");
  return 0;
}


int leapyear(int y) {
  return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);
}

int s2d(char *id, int s, int e) {
  int result = 0;
  for (int i = s; i <= e; i++)
    result = 10 * result + (id[i] - '0');
  return result;
}

int countdays(int y,int m,int d){

  int total=0;
  if(y<THISYEAR){

    for(int i=11;i>=m;i--){
      total += days[leapyear(y)][i];
    }
    total += days[leapyear(y)][m-1]-d+1;

    for(int i=y+1;i<THISYEAR;i++)
      total += leapyear(i)?366:365;

    for(int i=0;i<THISMONTH - 1;i++)
      total += days[leapyear(THISYEAR)][i];

    total += TODAY;
  }
  else{
    for(int i=y-1;i<THISMONTH-1 ;i++)
      total += days[leapyear(THISYEAR)][i];

    total += TODAY;
  }

  return total;
}

追问

还需要考虑输入的身份证号中出生年月是否合法。年份已经确定合法,但月可能不在1-12个月,日期也有可能超出当月最大日期

追答

第53行那里就是在判断这个,但是漏了一个条件

这程序还有不少可以改进的,比如判断不合法后可以直接输出No,不需要进行下去了

温馨提示:答案为网友推荐,仅供参考
第1个回答  2020-05-29
C语言设计程序放在身份证号码,可好像必须要吃到指定日期的天数才快乐。
相似回答