2

こんにちは、ユーザーが月の数を入力すると、アプリはそれが何月であるかを判断し、回答を表示し、月の日数を表示するコンソールアプリを作成しています。switch ステートメントが Main メソッドにあるときに機能していましたが、今では間違った月が表示されます。次のコードがあります。

namespace ConsoleCA2{

public enum Months
{
    January = 31,
    February = 28,
    March = 31,
    April = 30,
    May = 31,
    June = 30,
    July = 31,
    August = 31,
    September = 30,
    October = 31,
    November = 30,
    December = 31
};

public class Program
{
    public const string NEWLINE = "\n";     //constant for new line


    static void Main(string[] args)
    {
        try
        {

            //prompt user for month number.
            Console.Write("Enter a Number to find out what Month it is: ");

            //convert users answer to integer
            int userInput = Convert.ToInt16(Console.ReadLine());

            //declare and initalise
            int daysInMonth = 0;
            string answer = String.Empty;

            //call relevent calculation methods
            answer = DetermineMonth(userInput);
            daysInMonth = DetermineDaysInMonth(userInput);

            //Write users answer to screen
            Console.WriteLine(answer);

            //Prompt user, whether they want to know number of days in the
            //month
            Console.Write("Would you like to know the number of days in" +
                " {0}: ", answer);

            //assign users answer to variable
            string userAnswer = Console.ReadLine();

                //Output answer if needed.
                if (userAnswer == "yes".Trim().ToLower())
                {
                    Console.WriteLine("The number of days in {0} is: {1}", 
                        answer, daysInMonth.ToString());
                }
                else if (userAnswer == "no".Trim().ToLower())
                {
                    Console.WriteLine(NEWLINE);
                    Console.WriteLine("You answered No, Have a good day!");
                }
                else
                {
                    Console.WriteLine("Please answer yes or no.");
                }

            Console.Read(); //Pauses screen for user
        }
            //catch any errors.
        catch (Exception err)
        {
            Console.WriteLine("Error" + err.Message);
        }

    }


    /// <summary>
    /// Determines What month the use enters and returns string value
    /// </summary>
    /// <param name="userInput"></param>
    /// <returns>returns the month as string</returns>
    public static String DetermineMonth(int userInput)
    {
        switch (userInput)
        {
            case 1:
                return Months.January.ToString();
            case 2:
                return Months.February.ToString();
            case 3:
                return Months.March.ToString();
            case 4:
                return Months.April.ToString();
            case 5:
                return Months.May.ToString();
            case 6:
                return Months.June.ToString();
            case 7:
                return Months.July.ToString();
            case 8:
                return Months.August.ToString();
            case 9:
                return Months.September.ToString();
            case 10:
                return Months.October.ToString();
            case 11:
                return Months.November.ToString();
            case 12:
                return Months.December.ToString();
            default:
                return "Error";
        }



    }

    /// <summary>
    /// Determines how many days is in selected month as integer
    /// </summary>
    /// <param name="userInput"></param>
    /// <returns>returns how many days in month</returns>
    public static int DetermineDaysInMonth(int userInput)
    {
        switch (userInput)
        {
            case 1:
                return Convert.ToInt16(Months.January);
            case 2:
                return Convert.ToInt16(Months.February);
            case 3:
                return Convert.ToInt16(Months.March);
            case 4:
                return Convert.ToInt16(Months.April);
            case 5:
                return Convert.ToInt16(Months.May);
            case 6:
                return Convert.ToInt16(Months.June);
            case 7:
                return Convert.ToInt16(Months.July);
            case 8:
                return Convert.ToInt16(Months.August);
            case 9:
                return Convert.ToInt16(Months.September);
            case 10:
                return Convert.ToInt16(Months.October);
            case 11:
                return Convert.ToInt16(Months.November);
            case 12:
                return Convert.ToInt16(Months.December);
            default:
                return 0;
        }
    }

古い switch ステートメントは次のとおりです。

        switch (userInput)
        {
        case 1:
            answer = Months.January.ToString();
            daysInMonth = Convert.ToInt16(Months.January);
            break;
        case 2:
            answer = Months.February.ToString();
            daysInMonth = Convert.ToInt16(Months.February);
            break;
        case 3:
            answer = Months.March.ToString();
            daysInMonth = Convert.ToInt16(Months.March);
            break;
        case 4:
            answer = Months.April.ToString();
            daysInMonth = Convert.ToInt16(Months.April);
            break;
        case 5:
            answer = Months.May.ToString();
            daysInMonth = Convert.ToInt16(Months.May);
            break;
        case 6:
            answer = Months.June.ToString();
            daysInMonth = Convert.ToInt16(Months.June);
            break;
        case 7:
            answer = Months.July.ToString();
            daysInMonth = Convert.ToInt16(Months.July);
            break;
        case 8:
            answer = Months.August.ToString();
            daysInMonth = Convert.ToInt16(Months.August);
            break;
        case 9:
            answer = Months.September.ToString();
            daysInMonth = Convert.ToInt16(Months.September);
            break;
        case 10:
            answer = Months.October.ToString();
            daysInMonth = Convert.ToInt16(Months.October);
            break;
        case 11:
            answer = Months.November.ToString();
            daysInMonth = Convert.ToInt16(Months.November);
            break;
        case 12:
            answer = Months.December.ToString();
            daysInMonth = Convert.ToInt16(Months.December);
            break;
        default:
            answer = "Error";
            break;
    }

別の方法に変更するまではうまくいきましたが、そこから下り坂になりました。元に戻しても、まだ月が混同されますか?

とても混乱しました:S

助けてくれてありがとう...乱雑なコードを理解できるなら:p

4

6 に答える 6

6

NET Framework には膨大な量のコードが含まれています。必要なものを見つけるのが難しい場合もありますが、すでに何かが存在する可能性は高いです。また、検索には時間がかかりますが、将来の仕事に役立つ知識を身につけることができるので、有意義な時間です。

CultureInfo.CurrentCulture.DayFormatInfo.MonthNames
DateTime.DaysInMonth

using System.Globalization;
static void Main(string[] args)
{
    Console.Write("Enter a Number to find out what Month it is: ");

    int userInput = Convert.ToInt16(Console.ReadLine());
    if(userInput > 0 && userInput < 13)
    {            
         string monthName = CultureInfo.CurrentCulture.DayTimeFormat.MonthNames[userInput-1];
         int daysInMonth = DateTime.DaysInMonth(2013, userInput);
         ......

    }
}

うるう年も考慮する必要がある場合は、その年の入力を取得する必要がありますが、それは非常に簡単です

于 2013-07-20T09:56:17.303 に答える
1

を使用しenumて、定数の記号名を作成します。この場合、それはあなたが望むものではありません。

あなたが望むのは、値 A を指定すると値 B を返すルックアップ テーブルだと思います。あなたの場合、いくつかの配列を使用できます。

string[] monthNames = new string[]
{
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "November", "December"
};
int[] monthDays = new int[] {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

そして、ルックアップで月の名前と日数を取得できます。

int userInput = Convert.ToInt16(Console.ReadLine());
if (userInput < 1 || userInput > 12)
    Console.WriteLine("Error: invalid month.");
else
{
    answer = monthNames[userInput-1];
    daysInMonth = monthDays[userInput-1];
}

月や日に構造体やクラスを使用するなど、これを行う方法は他にもありますが、それらは少し高度なトピックです。

さらに、.NET には、日付と時刻を操作するためのこれらすべての機能とその他の機能を備えたDateTime 構造があります。本番プログラムでは、独自のものを作成するのではなく、それを使用します。

于 2013-07-20T09:39:55.017 に答える
1

これは、列挙型がすべて混同されているためです。

31 と 30 には繰り返し値があります。

これが実際の例です(ただし、それを最適化する方法は他にもあります。DateTimeクラスを使用するように)

public enum Months : int
{
    None = 0,
    January = 1,
    February = 2,
    March = 3,
    April = 4,
    May = 5,
    June = 6,
    July = 7,
    August = 8,
    September = 9,
    October = 10,
    November = 11,
    December = 12
};

public class Program
{
    public const string NEWLINE = "\n";     //constant for new line

    static void Main(string[] args)
    {
        try
        {
            //prompt user for month number.
            Console.Write("Enter a Number to find out what Month it is: ");

            //convert users answer to integer
            int userInput = Convert.ToInt16(Console.ReadLine());

            //declare and initalise
            int daysInMonth = 0;
            Months answer;

            //call relevent calculation methods
            answer = DetermineMonth(userInput);

            if (answer == Months.None) 
            {
                Console.WriteLine("Please enter a value between 1 and 12");
                return;
            }

            daysInMonth = DetermineDaysInMonth(answer);

            //Write users answer to screen
            Console.WriteLine(answer);

            //Prompt user, whether they want to know number of days in the
            //month
            Console.Write("Would you like to know the number of days in {0}: ", answer);

            //assign users answer to variable
            string userAnswer = Console.ReadLine();

            //Output answer if needed.
            if (userAnswer == "yes".Trim().ToLower())
            {
                Console.WriteLine("The number of days in {0} is: {1}", answer, daysInMonth.ToString());
            }
            else if (userAnswer == "no".Trim().ToLower())
            {
                Console.WriteLine(NEWLINE);
                Console.WriteLine("You answered No, Have a good day!");
            }
            else
                Console.WriteLine("Please answer yes or no.");

            Console.ReadLine(); //Pauses screen for user
        }
        //catch any errors.
        catch (Exception err)
        {
            Console.WriteLine("Error" + err.Message);
        }
    }

    /// <summary>
    /// Determines What month the use enters and returns string value
    /// </summary>
    /// <param name="userInput"></param>
    /// <returns>returns the month as string</returns>
    public static Months DetermineMonth(int userInput)
    {
        switch (userInput)
        {
            case 1:
                return Months.January;
            case 2:
                return Months.February;
            case 3:
                return Months.March;
            case 4:
                return Months.April;
            case 5:
                return Months.May;
            case 6:
                return Months.June;
            case 7:
                return Months.July;
            case 8:
                return Months.August;
            case 9:
                return Months.September;
            case 10:
                return Months.October;
            case 11:
                return Months.November;
            case 12:
                return Months.December;
        }
        return Months.None;
    }

    /// <summary>
    /// Determines how many days is in selected month as integer
    /// </summary>
    /// <param name="userInput"></param>
    /// <returns>returns how many days in month</returns>
    public static int DetermineDaysInMonth(Months userInput)
    {
        switch (Convert.ToInt32(userInput))
        {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                return 31;
            case 2:
                return 28;
            case 4:
            case 6:
            case 9:
            case 11:
                return 30;
        }
        return 0;
    }
}
于 2013-07-20T09:28:46.930 に答える
0

これを少し単純化し、列挙型の数値を月の数値と一致させることを検討してください。次に、その月の日を別の場所に保存します。

次に、(Months)userInput を実行して列挙型を取得し、少なくとも 1 つの switch ステートメントを削除できます。

列挙型が各値の一意の int を格納している限り、Dictionary またはその他の方法で各月の日を格納できます。

于 2013-07-20T09:40:36.203 に答える
0

これは、列挙型の使用方法ではありません。

それらは単なる静的なキーと値のペアではありません。そうであれば、整数型以上のものを使用できます。いいえ、それらは整数型のタイプセーフ ラッパー以上のものではありません。

あなたの問題はこれです:

public enum Months
{
    January = 31,
    February = 28,
    March = 31,
    April = 30,
    May = 31,
    June = 30,
    July = 31,
    August = 31,
    September = 30,
    October = 31,
    November = 30,
    December = 31
};

これは、CLR が知る限り、1 月、3 月、5 月、7 月、8 月、10 月、12 月がまったく同じであることを意味します。4月、6月、9月、11月も同様。

これを行う正しい方法は次のようになります。

public enum Months
{
    None = -1,
    January = 1,
    February = 2,
    March = 3,
    April = 4,
    May = 5,
    June = 6,
    July = 7,
    August = 8,
    September = 9,
    October = 10,
    November = 11,
    December = 12
};

そして、あなたのDetermineMonth方法はこれだけです:

public static Months DetermineMonth(int userInput)
{
    Months temp = (Months)userInput;
    return Enum.IsDefined(typeof(Months), temp) ? temp : Months.None; 
}

そして、DetermineDaysInMonthこれは次のようになります。

public static int DetermineDaysInMonth(int userInput)
{
    if (!((Months[])Enum.GetValues(typeof(Months))).Contains((Months)userInput)
        return 0;
    else return DateTime.DaysInMonth(DateTime.Today.Year, userInput);
}
于 2013-07-20T09:48:56.443 に答える
0

日数を返すには、拡張メソッドを使用できます-enum

public enum Months
{
    January,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December
}

public static class MonthsExtensions
{
    public static int DaysInMonths(this Months month)
    {
        switch (month)
        {
            case Months.January:
            case Months.March:
            case Months.May:
            case Months.July:
            case Months.August:
            case Months.October:
            case Months.December:
                return 31;

            case Months.April:
            case Months.June:
            case Months.September:
            case Months.November:
                return 30;

            case Months.February:
                return 28;
        }
        return 0;
    }

次に、このような日数を取得できます-

int daysInMonths = Months.January.DaysInMonths();
于 2013-07-20T09:49:40.607 に答える