我如何接受C#中的空白?

时间:2016-12-23 11:23:39

标签: c#

我正在尝试创建一个程序,通过记录每个主题中获得的标记数来计算考试结果。它几乎完成但我遇到一个错误,即如果用户只是按Enter而不是输入值,应用程序将不会继续。还有什么方法可以缩短这段代码吗?

Console.WriteLine("Danyal's result calculator for students of class IX. Enter the marks requested, if not applicable leave blank and press enter :)");
Console.Write("Enter your Urdu marks: ");
int urdu = int.Parse(Console.ReadLine());
Console.Write("Enter your Maths marks: ");
int maths = int.Parse(Console.ReadLine());
Console.Write("Enter your English Literature marks: ");
int lit = int.Parse(Console.ReadLine());
Console.Write("Enter your Biology marks: ");
int bio = int.Parse(Console.ReadLine());
Console.Write("Enter your Chemistry marks: ");
int chem = int.Parse(Console.ReadLine());
Console.Write("Enter your Islamiat marks: ");
int isl = int.Parse(Console.ReadLine());
Console.Write("Enter your Physics marks: ");
int physics = int.Parse(Console.ReadLine());
Console.Write("Enter your Computer marks: ");
int comp = int.Parse(Console.ReadLine());
Console.Write("Enter your English Language marks: ");
int lang = int.Parse(Console.ReadLine());
Console.Write("Enter your Pakistan Studies marks: ");
int pst = int.Parse(Console.ReadLine());


int total = urdu + maths + lit + lang + bio + chem + physics + isl + comp + pst;
Console.WriteLine("Your total marks are {0} out of 1000", total);
float percentage = total * 100 / 1000;
Console.WriteLine("Your percentage is: {0}%",percentage);
Console.WriteLine("Note: the percentage has been rounded off. Please share this program with other classmates, also I am open to suggestions for creating more helpful programs.");
Console.ReadLine();

2 个答案:

答案 0 :(得分:4)

如果用户将其留空或输入无效值,我不确定您想要做什么,但您可以这样做。

        Dictionary<string,int> grades = new Dictionary<string, int>
        {
            { "Urdu", 0 },
            { "Maths", 0 },
            { "English", 0 },
            { "Biology", 0 },
            { "Chemistry", 0 },
            { "Islamiat", 0 },
            { "Physics", 0 },
            { "Computer", 0 },
            { "English Language", 0 },
            { "Pakistan Studies", 0 },
        };

        foreach (string grade in grades.Keys.ToArray())
        {
            Console.WriteLine(string.Format("Enter your {0} marks: ", grade));
            int mark;
            if (int.TryParse(Console.ReadLine(), out mark))
                grades[grade] = mark;
        }
        int total = grades.Sum((g) => g.Value);

在此示例中,如果使用错误输入,则成绩将默认为0.如果您愿意,可以将if try解析更改为循环并请求一个好的值,直到输入一个。

答案 1 :(得分:1)

这是一个不遵守DRY原则的明显案例。您正在重复基本相同的操作,不要这样做。重构代码,以便在一个地方解决常见的模式或行为。

你会怎么做?

  1. 创建一个提示用户输入特定信息的方法。用户需要什么?描述他必须做什么的信息。用户需要做什么?输入有效输入。好的,考虑到这一点,以下方法的原型似乎是一个很好的起点:

    private static int GetUserInput(string message) { ... }
    
  2. 嗯...输入有效输入。这意味着我们需要某种验证,所以再次让我们想一想如何解决这个问题:

    private static int ValidateUserInput(string input) { ... }
    

    这够好吗?嗯......不太好。如果用户输入的号码不正确会怎样?没有方便的方式来传达输入对呼叫者无效。我们可以返回-1,或者我们可以抛出一个异常,但两者看起来都很糟糕。

    最好的解决方案是返回两个值;一个告诉我们输入是否有效,另一个告诉我们输入是什么。在c#中,这并不是非常严格(至少在c#7出现之前)。这样做的方法是使用out参数:

    private static bool ValidateUserInput(string message, out int input) { ... }
    

    现在这种方法完全符合我们的目的。返回值告诉我们输入是否有效,out参数input为我们提供了验证值(或者如果验证失败,我们就会忽略它。)

  3. 如果您基本上只想要总和和平均值,为什么要为每个标记创建一个int变量?让我们创建一个List<int>,我们存储所有标记。

    另一个选项是,如果要跟踪哪个标记对应于哪个主题,将使用Dictionary<string, key>,其中键是主题名称,值是其对应标记。但是现在让我们使用List<int>

  4. 考虑到这些,我们可以建立我们的解决方案:

    public static void ComputeMarksSummary()
    {
         var marks = new List<int>();
    
         marks.Add(GetUserInput("Enter your Urdu marks: "));
         marks.Add(GetUserInput("Enter your Maths marks: : "));
         marks.Add(GetUserInput("Enter your English Literature marks: "));
         marks.Add(GetUserInput("Enter your Biology marks: "));
         marks.Add(GetUserInput("Enter your Chemistry marks: "));
         marks.Add(GetUserInput("Enter your Islamiat marks: "));
         marks.Add(GetUserInput("Enter your Computer marks: "));
         marks.Add(GetUserInput("Enter your English language marks: "));
         marks.Add(GetUserInput("Enter your Pakistan studies marks: "));
    
         var total = marks.Sum();
         Console.WriteLine("Your total marks are {0} out of 1000", total);
         Console.WriteLine("Your percentage is: {0}%", total/10.0); //note the 10.0 to force double division, not integer division where 44/10 would be 4 not 4.4
         Console.WriteLine("Note: the percentage has been rounded off. Please share this program with other classmates, also I am open to suggestions for creating more helpful programs.");
         //WRONG! Percentage is not rounded off, its truncated: 9/10 is 0 in integer division.
         Console.ReadLine();
    }
    
    private static int GetUserInput(string message)
    {
         int mark;
    
         while (true)
         {
              Console.WriteLine(message);
              var input = Console.ReadLine();
    
              if (!ValidateUserInput(input, out mark))
              {
                   Console.WriteLine("Invalid input, please try again.");
              }
              else
              {
                   return mark;
              }
         }
    }
    
    private static bool ValidateUserInput(string message, out int input)
    { 
        //left as an excerice. Hint: look into int.TryParse(...);
        //here you could decide if a blank input should be valid and parsed as zero. 
    }
    
    哇,现在看起来好多了......但是,嘿,我们仍然可以做得更好一些。怎么了marks.Add(....)?我们不能再重构代码吗?是的,我们基本上总是要求相同的事情,只有主题名称改变。我们做这样的事情怎么样:

    public static void ComputeMarksSummary(IEnumerable<string> subjectNames)
    {
         var marks = new List<int>();
    
         foreach (var subject in sujectNames)
         {
             marks.Add(GetUserInput(string.Format("Enter your {0} marks: ", subject)));
         }
    
         var total = marks.Sum();
         Console.WriteLine("Your total marks are {0} out of 1000", total);
         Console.WriteLine("Your percentage is: {0}%", total/10.0); //note the 10.0 to force double division, not integer division where 44/10 would be 4 not 4.4
         Console.WriteLine("Note: the percentage has been rounded off. Please share this program with other classmates, also I am open to suggestions for creating more helpful programs.");
         Console.ReadLine();
    }
    

    你可以这样称呼它:

    ComputeMarksSummary(new string[] { "Urdu", "Maths", ... );
    

    看起来那么干净吗?