【问题标题】:Print the month corresponding to appropriate input打印对应于适当输入的月份
【发布时间】:2011-03-25 23:28:59
【问题描述】:

我必须编写一个程序,由用户输入两个整数 a 和 b,其中 a 对应于一年中的月份(1 = jan,2 = feb 等)。该程序必须打印“a”之后的月份和接下来的“b”个月。这是我到目前为止所拥有的,但是对于我输入的每两个整数,我总是得到相同的输出:“一月,二月”。任何帮助表示赞赏。

#include<stdio.h>

        enum month {jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec}; /*This
allows yoou to name a finite set and to declare identifiers*/
        typedef enum month      month;

month next_month(month M)  /*this is a function definition*/
{
        switch (M) /* like an if-else statement, if this month is true goto the M=month you chose*/
        {
        case  jan:
                M=feb;break;
        case  feb:
                M=mar;break;
        case  mar:
                M=apr;break;
        case apr:
                M=may;break;
        case may:
                M=jun;break;
        case jun:
                M=jul;break;
        case jul:
                M=aug;break;
        case aug:
                M=sep;break;
        case sep:
                M=oct;break;
        case oct:
                M=nov;break;
        case nov:
                M=dec;break;
        case dec:
                M=jan;break;
        }
        return M;
}
void print_month (month M)  /*this is a function definition*/
{
        switch (M)  /* like an if-else statement, if this month is true goto the M=month you chose*/
        {
        case jan:
                printf("January");break;
        case feb:
                printf("February");break;
        case mar:
                printf("March");break;
        case apr:
                printf("April");break;
        case may:
                printf("May");break;
        case jun:
                printf("June");break;
        case jul:
                printf("July");break;
        case aug:
                printf("August");break;
        case sep:
                printf("September");break;
        case oct:
                printf("October");break;
        case nov:
                printf("November");break;
        case dec:
                printf("December");break;
        }
}
int main(void)
{
        month M, N, sat;
        printf("Please enter two integers:\n");
        scanf("%d%d", &M, &N);
        for (M = jan; M <= N; ((int)M++))
        {
                printf(" ");
                print_month(M);  /*function call to print month*/
                printf(" ");
                print_month(next_month(M));  /*function call to print previous month*/
                putchar('\n');
                return;
        }
}

【问题讨论】:

  • 如果这是一个家庭作业问题,你应该这样标记它。
  • 你有调试器吗?使用调试器并逐行检查代码将对您的情况有很大帮助...您将能够看到哪些代码的行为与您的预期不同。

标签: c


【解决方案1】:

你在 main 中有这个

    scanf("%d%d", &M, &N);
    for (M = jan; M <= N; ((int)M++))
    {
         /* ... */
    }

所以...在 scanf 行中,您将 M(和 N)更改为用户提供的值
之后,您将 M 设置为 jan,实际上失去了用户选择的内容。

您需要重新审视自己的做法。

【讨论】:

    【解决方案2】:

    我对改进程序的建议是将 switch 语句替换为月份名称数组。它会更容易编程和阅读。

    只要您可以用数据结构替换代码,这通常是一个很大的改进。这是您以后进行编程时要记住和使用的东西。

    所以按照我的建议使用月份数组看起来有点像这样:

    #include <stdio.h>
    
    const char* months[12] = {
     "January", "February", "March", "April", "May", "June",
     "July", "August", "September", "October", "November", "December"
    };
    
    int main(void)
    {
        int m;
        printf("Enter month: ");
        scanf("%d", &m);
        if( 1 <= m && m <= 12 ) {
            printf("%s\n", months[m-1]);
        }
        return 0;
    }
    

    【讨论】:

    • 使用宏会更好——不需要维护两个列表。
    • @Danny:您需要提供更多详细信息。使用宏做什么?
    【解决方案3】:

    return 表示从当前函数返回,所以在你的 for 循环的第一次迭代结束时,你从主函数返回,程序退出。

    【讨论】:

      【解决方案4】:

      试试这个代码:

      int main(void)
      {
              int a, b, m;
              printf("Please enter two integers between 1-12:\n");
              scanf("%d%d", &a, &b);
              for (m=a+1; b; b--, m++)
              {
                      printf(" ");
                      print_month(m);  /*function call to print month*/
                      putchar('\n');
              }
      }
      

      保重, 贝科

      附言。编辑:

      另外,将枚举行更改为:

          enum month {jan=1,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec};
      

      并注意可能的溢出 a+b>12

      第二。版: 另一种解释可能有用:你不能在这样的循环中使用return 并期望循环会运行,因为在计算机运行return 时它会永远退出程序。

      【讨论】:

      • 我不明白为什么有人会在肯定能解决问题的代码中投反对票。那太蹩脚了。我们试图在这里提供帮助。有更好的答案,投票给他们。 186 代表并没有那么大,不会感到非常苛刻。
      • 顺便说一句,@Zan Lynx 提出的使用 const char* months[12] = { "January", ... 的建议比我的要好得多,但它解决了另一个问题,而不是问题。所以在你的代码中去吧。我什至在我的一些程序中使用这种形式,但我忘了包括在我的答案中。实际上,问题是为什么它不起作用。不改变作者的思维方式。现在为时已晚。如果另一个 ACA 再次投票否决,也许我应该完全删除这个答案。
      【解决方案5】:

      查看“%”和宏的 C/C++ 文档 - “#define”。 对于这个问题,Switch 是不必要的,效率低下 并使代码变长。

      增量和模数可用于增加月份。 枚举值可以用一个宏替换 值代码与包含相同代码的字符串。

      使用宏枚举到字符串:
      MSDN link - Stringizing Operator (#)

      有很多方法可以使用它来将枚举转换为字符串 (Google it),包括:

      // Use correct number of parameters here (can use multiple macros)
      #define ENUM_MACRO(name, offset, v1, v2, v3, v3)\
          enum name { v1 = offset, v2, v3, v4};\
          const char name##Strings[] = { #v1, #v2, #v3 };\
          const char* name##ToString(value) { return name##Strings[value - offset]; }
      
      // This way you do not have two different
      // lists of months to maintain in your code
      // (the preprocessor creates them)
      ENUM_MACRO(Month, 1, January, February, March);
      
      //
      // usage:
      //
      Month month = Month::Janurary;
      const char* st = MonthToString(month);
      
      //
      // Incrementing month taking offset (1) and max (12) into account
      //
      month = (month + 1) % 12 + Month::Janurary;
      

      使用这些方法可以大大减少代码的大小,使其更易于阅读和维护。此外 - 您可以通过摆脱所有分支来提高性能。

      免责声明 - 我没有编译这段代码,是从内存中编写的。

      【讨论】:

      • 投票反对鼓励某人学习和提高,而不是给他家庭作业的答案是蹩脚的!
      • 交换机效率低下?对于这个令人难以置信的说法,您有任何支持信息吗?
      • 我没有投票给你,但我看不出你的回答在这里有什么帮助。我不知道如何使用“%”和宏来改进他的程序,而且我已经编写 C 语言 15 年了。 :-)
      • 哦!模运算符:% 并使用预处理器宏的字符串化功能将月份名称用作枚举和字符串。
      • @Danny 抱歉让您久等了。我没有得到通知。我使用enum Month month=January; 而不是Month month = Month::Janurary;。此外,等式是month = ((++month)%13)?:January;,而不是month = (month + 1) % 12 + Month::Janurary;。这真的很好。我这里只是用这个例子来解释另一个list question! ;)
      【解决方案6】:
      include <stdio.h>
      
      const char* months[12] = {
       "January", "February", "March", "April", "May", "June",
       "July", "August", "September", "October", "November", "December"
      };
      
      int main(void)
      {
          int m;
          printf("Enter month: ");
          scanf("%d", &m);
          if( 1 <= m && m <= 12 ) {
              printf("%s\n", months[m-1]);
          }
      
      
          return 0;
      }
      

      为我工作。谢谢。

      【讨论】:

        猜你喜欢
        • 2016-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-10
        • 2019-11-12
        相关资源
        最近更新 更多