【问题标题】:c++ calendar program format, display, offsetc++日历程序格式、显示、偏移
【发布时间】:2016-12-02 06:10:33
【问题描述】:

我正在用 c++ 编写一个程序,它将打印一整年的日历。该程序将询问用户他们想输入哪一年,以便确定它是否是闰年。然后它会要求用户询问他们希望从 1 月 1 日st 的哪一天开始计数。然后它应该在一月的每一天计算,然后移动到二月,然后计算每一天,然后继续前进等。但是它不能正确打印每个月。我还被要求不要使用 % 运算符。任何可以使我的程序打印正确日历的帮助将不胜感激,请不要发布使用 % 运算符的建议。

#include<iostream>
#include<iomanip>
using namespace std;
/****************************************************************************************
                             Prototypes
****************************************************************************************/
void getyear(int& year , int& days_per_yr);
void list_months(int imonth, int iyear);
void firstday(int& mostart);
void start_month(int& mostart);
int get_numdays(int xmonth, int numdays, int year);
void listdays(int numdays, int& mostart);
bool isLeapYear(int year);
void printMonth();
/****************************************************************************************
                           Main
****************************************************************************************/
int main(){    
printMonth();
}

void printMonth(){ // calls all the functions needed to print the calendar
    int year;
    int day;
    int month;
    int mostart;
    int days_per_yr; 
    int numdays; // number of days per month is stored here
    cout << "What year do you want a calendar for? ";
    getyear(year, days_per_yr);   
    cout << "What day of the week does January 1 fall ";
    cout <<"on (0 for Sunday, 1 for Monday, etc.)? ";
    firstday(mostart);
    cout << year << "\n" <<endl;
    for (month=1; month <= 12; ++month){
    list_months(month, year);
    start_month(mostart);
    numdays=get_numdays(month, numdays, year);
    listdays(numdays, mostart);
    }
}







void getyear(int& year, int& days_per_yr){ //gets the year from the user and sends it back to the printMonth function
                         // this function is vital for the isLeapyear function to work properly
    cin >> year;
    if (isLeapYear(year) == true){
    days_per_yr = 366;}
    else{
    days_per_yr = 365;}
}








void list_months(int imonth, int iyear){ // lists every month needed with the days spaced out correctly
    switch (imonth){
    case 1: cout<< "        January" << endl;
    cout << "  S  M  T  W  T  F  S  "<< endl;
    cout <<"-----------------------"<< endl;
    break;
    case 2: cout<< "        Febuarry" << endl;
    cout << "  S  M  T  W  T  F  S  "<< endl;
    cout <<"-----------------------"<< endl;
    break;
    case 3: cout<< "        March" << endl;
    cout << "  S  M  T  W  T  F  S  "<< endl;
    cout <<"------------------------"<< endl;
    break;
    case 4: cout<< "        April" << endl;
    cout << "  S  M  T  W  T  F  S  "<< endl;
    cout <<"------------------------"<< endl;
    break;
    case 5: cout<< "        May" << endl;
    cout << "  S  M  T  W  T  F  S  "<< endl;
    cout <<"------------------------"<< endl;
    break;
    case 6: cout<< "        June" << endl;
    cout << "  S  M  T  W  T  F  S  "<< endl;
    cout <<"------------------------"<< endl;
    break;
    case 7: cout<< "        July" << endl;
    cout << "  S  M  T  W  T  F  S  "<< endl;
    cout <<"------------------------"<< endl;
    break;
    case 8: cout<< "        August" << endl;
    cout << "  S  M  T  W  T  F  S  "<< endl;
    cout <<"------------------------"<< endl;
    break;
    case 9: cout<< "        September" << endl;
    cout << "  S  M  T  W  T  F  S  "<< endl;
    cout <<"------------------------"<< endl;
    break;
    case 10: cout<< "        October" << endl;
    cout << "  S  M  T  W  T  F  S  "<< endl;
    cout <<"------------------------"<< endl;
    break;
    case 11: cout<< "        November" << endl;
    cout << "  S  M  T  W  T  F  S  "<< endl;
    cout <<"------------------------"<< endl;
    break;
    case 12: cout<< "        December" << endl;
    cout << "  S  M  T  W  T  F  S  "<< endl;
    cout <<"------------------------"<< endl;
    break;
    }
}






void firstday(int& mostart){ // gets the input from the user for the start_month(); function

    cin >> mostart;
    cout <<"\n";
    }






void start_month(int& mostart){ //does the spacing so that the desired day entered by the user is displayed correctly

    if(mostart==0){
     cout << setw(3);
     }
     else if (mostart == 1){
     cout << setw(6);
     }
     else if (mostart == 2){
     cout << setw(9);
     }
     else if (mostart == 3){
     cout << setw(12);
     }
     else if (mostart == 4){
     cout << setw(15);
     }
     else if (mostart == 5){
     cout << setw(18);
     }
     else if (mostart == 6){
     cout << setw(21);
     }
     else if (mostart == 7){
     mostart = 1;
     }

     }







int get_numdays(int xmonth, int numdays, int year){ // sets correct amount of days per month. If there is a leap year febuarry will have 29 days.
    if ( xmonth == 1)
    numdays = 31;
    else if ( xmonth == 2){if (isLeapYear(year) == true)
    numdays = 29;
    else
    numdays = 28;}
    else if ( xmonth == 3)
    numdays = 31;
    else if ( xmonth == 4)
    numdays = 30;
    else if ( xmonth == 5)
    numdays = 31;
    else if ( xmonth == 6)
    numdays = 30;
    else if ( xmonth == 7)
    numdays = 31;
    else if ( xmonth == 8)
    numdays = 31;
    else if ( xmonth == 9)
    numdays = 30;
    else if ( xmonth == 10)
    numdays = 31;
    else if ( xmonth == 11)
    numdays = 30;
    else if ( xmonth == 12)
    numdays = 31;
    return numdays;
}






void listdays(int numdays, int& mostart){ //This function counts out every single day depending on the month.
    int oneday;

    for (oneday=1; oneday <= numdays; ++oneday){
    if(mostart <= 6){
    cout << oneday <<"  ";
    mostart++;
    }
    else{
     cout << endl;
     mostart=0;
     start_month(mostart);

     cout << oneday <<"  ";
     mostart++;
    } 
    };


    cout << endl;
    }











bool isLeapYear(int year){ //determines if the year entered is a leapyear or not if it is a leap year it will return true
                           // if true is returned then it will execute a condition that will make febuary a day longer.
                           // If the condition returns false then febuary will continue to be 28 days.
    if (year % 400 == 0){    
    return true;
    }

    if (year % 100 == 0){    
    return false;
    }
    if (year % 4 == 0){
    return true;
    }
    return false;
    }

【问题讨论】:

  • 题外话:cout &lt;&lt; " S M T W T F S "&lt;&lt; endl; cout &lt;&lt;"-----------------------"&lt;&lt; endl; 通用于所有情况,可以拉出来为你节省一大堆冗余代码
  • isLeapYear 使用 % 运算符,所以...为什么您要求不要发布使用它的解决方案?测验是为您准备的,还是为我们所有人准备的?此外,1 月 1 日的工作日完全由年份决定。
  • 只需使用 Julian Day Number 公式,不要理会那些复杂的逻辑细节 - en.wikipedia.org/wiki/Julian_day
  • @LuisColorado 如果年份是整数,则不需要%bool isLeapYear(int year) { return (year/400*400==year || year/100*100!=year) &amp;&amp; year/4*4==year; }
  • @JerryJeremiah,我知道,我的问题是因为 OP 希望我们努力不使用 % 运算符,但随后他在他发布的代码中使用它。这个世界没有正义吗? :)

标签: c++


【解决方案1】:

廉价的黑客:

start_month 中确保打印出一个字符来移动流

cout << setw(2) << " "; // was setw(3), but we added a manual space.

因为我们将在listdays 中使用setw(2) 来始终为每天的数字打印两个字符,这将消除start_month 中的setw

cout << setw(2) << oneday << "  ";

然后根据需要添加空格和填充,确保所有内容对齐。

编辑

好的。也许这很令人困惑。这就是问题所在:cout &lt;&lt; oneday &lt;&lt;" "; 打印出一个整数。前 9 个是一个数字宽。接下来的 20 左右是 2 位数宽。为了将 1 位数字与 2 位数字对齐,1 位数字必须占用 2 位空间。

那么让我们这样做,好吗?

void listdays(int numdays, int& mostart){ //This function counts out every single day depending on the month.
    int oneday;

    for (oneday=1; oneday <= numdays; ++oneday){
    if(mostart <= 6){
    cout << setw(2) << oneday <<"  ";
    mostart++;
    }
    else{
     cout << endl;
     mostart=0;
     start_month(mostart);

     cout << setw(2) << oneday <<"  ";
     mostart++;
    } 
    };


    cout << endl;
    }

但这会破坏start_month,因为cout &lt;&lt; setw(2) &lt;&lt; oneday &lt;&lt;" "; 只是要重置cout &lt;&lt; setw(3); 和他的朋友设置的宽度。快速解决方案:我们需要设置写入宽度,然后写入一个字符来占用该空间。

void start_month(int& mostart){ //does the spacing so that the desired day entered by the user is displayed correctly

    if(mostart==0){
     cout << setw(2) << " ";
     }
     else if (mostart == 1){
     cout << setw(6) << " ";
     }
     else if (mostart == 2){
     cout << setw(10) << " ";
     }
     else if (mostart == 3){
     cout << setw(14) << " ";
     }
     else if (mostart == 4){
     cout << setw(18) << " ";
     }
     else if (mostart == 5){
     cout << setw(22) << " ";
     }
     else if (mostart == 6){
     cout << setw(26) << " ";
     }
     else if (mostart == 7){
     mostart = 1;
     }

     }

现在,如果你真的想踢,你可以说,“把所有这些if/else if 块拧开”并使用数学。看看上面的宽度数字 2, 6, 10, 14, 18, 22, 26。看到图案了吗? 2 + mostart * 4。不需要任何 steenking 功能!我可能有错误的凝视状态或步幅。这很容易解决。换一个号码。

OP 的大部分条件逻辑都可以用简单的数学运算代替。这就是为什么我称这个答案的原始剪辑为廉价黑客。

剩下的就是重新对齐所有的字符串文字。如果 OP 想不通,我也帮不了他们。

【讨论】:

  • 你能解释更多吗?您的回答非常含糊,没有提供任何明确性。遵循这些说明会使我的程序更加混乱。
  • 我刚做了,但它被吃掉了。不知道发生了什么。前一分钟我正在打字,下一分钟是my computer was playing this。一定是按了热键按钮并加载了快捷方式,因为这完全是我的快捷方式中的那种东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多