一个日期处于该年的第几天 - c语言实现

觉得不同的解法还挺有意思的,就分享一下~

问题描述:输入一个日期,格式yyyy-MM-dd,判断这个日期是当年的第几天。建议使用switch。
方便起见,直接写在主函数了。

思路一、没有使用switch,用了循环,数组存储月份的最大天数,最后累加。

#include<stdio.h>

int main()
{
    //闰年的月份
    int leapYear[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
    //平年的月份
    int commonYear[12] = {31,28,31,30,31,30,31,31,30,31,30,31};

    printf("input date(yyyy-MM-dd):");
    int year,month,day;
    scanf("%d-%d-%d",&year,&month,&day); //没有处理字符输入。

    //isLeapYear - 是否是闰年。 invalidInput - 是否有错误输入。
    //发现gcc编译器居然不支持bool。有说法是c++才支持bool型,觉得还是很神奇,以前没遇到过。
    int isLeapYear = 0, invalidInput = 0;
    if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
    {
        isLeapYear = 1;
    }

    //检查年份
    if(year > 9999)
    {
        printf("invalid year");
        invalidInput = 1;
    }

    //检查月份
    if(month <= 0 || month > 12)
    {
        printf("invalid month");
        invalidInput = 1;
    }

    //检查天数,闰年则检查learYear数组,平年则检查commonYear数组.
    if( (isLeapYear && day <=0 || day > leapYear[month - 1])
       ||
       (!isLeapYear && day <= 0 || day > commonYear[month - 1])
       )
    {
        printf("invalid day");
        invalidInput = 1;
    }

    //假设输入都合法了,这里没有处理invalidInput
    int result = 0;
    //累加月份天数
    int i = 0; //以及竟然不支持for循环内部声明i
    for(i = 0; i < month - 1; i++){
        if(isLeapYear)
        {
            result += leapYear[i];
        }
        else{
            result += commonYear[i];
        }
    }
    //加上天数
    result += day;
    //输出结果
    printf("the date is in the %d day of the year.",result);
}

思路二:利用switch自动往下执行的特性,写出简洁的代码:

#include<stdio.h>

int main()
{
    int exit = 0;
    int year,month,day;
    int res = 0;   
    //循环,可以多次输入。exit=1是终止条件
    while(exit == 0)
    {
    printf("input date(yyyy-MM-dd):");
    scanf("%d-%d-%d",&year,&month,&day); //没有处理字符输入,输入检测上面已经写过,假设参数都正确
    res = day;
    //假设月份只在1~12之间,代码正常执行。
    switch(month)
    {
        case 12: res += 30; //当前是12月的话,就加上11月的天数
        case 11: res += 31; //11月,就加上10月的天数
        case 10: res += 30; //同上
        case 9: res += 31;
        case 8: res += 31;
        case 7: res += 30;
        case 6: res += 31;
        case 5: res += 30;
        case 4: res += 31;
        case 3: //2月,特殊处理
            {
                if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) res += 29;
                else res += 28;
            }
        case 2: res += 31;
    }
    printf("the date is in the %d day of the year\n",res);
    printf("input 0 to try again,otherwise exit: ");//输入0继续测试,其他输入会退出。
    scanf("%d",&exit);
    }
}

因为switch如果没有遇到break语句会继续执行下一个case的语句,利用这个特性,把月份逆序排下来。
期间遇到 在codeblocks上可以运行的代码拷贝到VC上无法正常出结果 的问题,把year、month、day和res的声明放到循环外部即可解决。

这个问题还可以再拓展一下,比如算出两个日期的间隔天数,或者反过来求特定间隔天数的日期。

发布了52 篇原创文章 · 获赞 16 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Tuzi294/article/details/70141568