天数包括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,不需要进行下去了