2014-11-03 116 views
0

我有一个任务来构建一个学生测验分数应用程序。
我有一个结构来保存一个学生的名字,一个数组来保存5个测试成绩和一个平均分数。我为6名学生创建了一系列结构。用户输入通过文本框设置。我需要计算每个学生的平均值。 作业要求: 应用程序应该具有存储:Name(字符串),Test Scores(5个双精度数组)和Average(双精度)的结构。它应该有6个结构变量的数组来匹配6名学生。它应该允许用户输入每个学生的数据,并计算每个学生的平均测试分数。用户需要能够将打印数据保存,读取和/来自文件等学生考试分数错误地计算平均分

它不应该接受低于0或以上分数100

我已经阅读了这个几个职位,但一直没能与现有的职位解决,并花了最后2天试图解决。现在我没有得到正确的平均值。
我还需要能够打印和检索信息,但我首先要解决这个问题。我已经尝试了5和6的最大计数为学生和4和5的最大计数为测试。我相信我的数字是正确的,但许多帖子有不同的数字,但是当我使用这些数字时,我在调试模式下运行时学生数为7,所以我不是100%确定,但相信这是正确的。它看起来总和没有正确添加,我尝试了很多方法来修复,甚至尝试初始化回到0之前移动到下一个数字,但我迄今尝试过的东西似乎工作。因此,对于每组成绩而言,Try Catch声明的原因是不同的。我现在离开,以防万一我可能需要分开。

这是我的代码。任何帮助表示赞赏。
fyi-由于某些原因,代码不会在Imports System.IO上启动,因此在“输入代码位于此处”下的初始代码不会显示为vb。请让我知道如何解决以后的帖子。

谢谢!

Imports System.IO 

Public Class Form1 

    'Class level variables 
    Const intMAX_STUDENTS As Integer = 5 'Number of Students 
    Const intMAX_TESTS As Integer = 4 'Number of Tests 
    Private strFilename As String = "StudentReport.txt" 'Document File name 

    Private student(intMAX_STUDENTS) As StudentRecord 'Array for student names 

    Structure StudentRecord 

     Dim strStudent As String 
     Dim dblTestScores() As Double 
     Dim dblAverage As Double 
    End Structure 

    Sub CalcAverage() 

     ImportNames() 

     'Variable to hold the total of the grades. 
     Dim dblGradesTotal0 As Double = 0 
     Dim dblGradesTotal1 As Double = 0 
     Dim dblGradesTotal2 As Double = 0 
     Dim dblGradesTotal3 As Double = 0 
     Dim dblGradesTotal4 As Double = 0 
     Dim dblGradesTotal5 As Double = 0 

     'Add scores to the array 
     For intIndex = 0 To intMAX_STUDENTS 
      ReDim student(intIndex).dblTestScores(4) 'Scores per student 
     Next 

     Try 
      'Get grades for first student 
      student(0).dblTestScores(0) = ValidInput(CDbl(txtGrade00.Text)) 
      student(0).dblTestScores(1) = ValidInput(CDbl(txtGrade01.Text)) 
      student(0).dblTestScores(2) = ValidInput(CDbl(txtGrade02.Text)) 
      student(0).dblTestScores(3) = ValidInput(CDbl(txtGrade03.Text)) 
      student(0).dblTestScores(4) = ValidInput(CDbl(txtGrade04.Text)) 

      For Each i As StudentRecord In student 
       For Each a As Double In i.dblTestScores 
        dblGradesTotal0 += a 
       Next 
      Next 

      lblAvg0.Text = CStr(dblGradesTotal0/intMAX_TESTS) 
     Catch ex As Exception 
      MessageBox.Show("Be sure to enter a valid numeric score") 
     End Try 

     Try 
      'Get grades for second student 
      student(1).dblTestScores(0) = ValidInput(CDbl(txtGrade10.Text)) 
      student(1).dblTestScores(1) = ValidInput(CDbl(txtGrade11.Text)) 
      student(1).dblTestScores(2) = ValidInput(CDbl(txtGrade12.Text)) 
      student(1).dblTestScores(3) = ValidInput(CDbl(txtGrade13.Text)) 
      student(1).dblTestScores(4) = ValidInput(CDbl(txtGrade14.Text)) 

      For Each i As StudentRecord In student 
       For Each b As Double In i.dblTestScores 
        dblGradesTotal1 += b 
       Next 
      Next 

      lblAvg1.Text = CStr(dblGradesTotal1/intMAX_TESTS) 
     Catch ex As Exception 
      MessageBox.Show("Be sure to enter a valid numeric score") 
     End Try 

     Try 
      'Get grades for third student 
      student(2).dblTestScores(0) = ValidInput(CDbl(txtGrade20.Text)) 
      student(2).dblTestScores(1) = ValidInput(CDbl(txtGrade21.Text)) 
      student(2).dblTestScores(2) = ValidInput(CDbl(txtGrade22.Text)) 
      student(2).dblTestScores(3) = ValidInput(CDbl(txtGrade23.Text)) 
      student(2).dblTestScores(4) = ValidInput(CDbl(txtGrade24.Text)) 

      For Each i As StudentRecord In student 
       For Each c As Double In i.dblTestScores 
        dblGradesTotal2 += c 
       Next 
      Next 

      lblAvg2.Text = CStr(dblGradesTotal2/intMAX_TESTS) 
     Catch ex As Exception 
      MessageBox.Show("Be sure to enter a valid numeric score") 
     End Try 

     Try 
      'Get grades for fourth student 
      student(3).dblTestScores(0) = ValidInput(CDbl(txtGrade30.Text)) 
      student(3).dblTestScores(1) = ValidInput(CDbl(txtGrade31.Text)) 
      student(3).dblTestScores(2) = ValidInput(CDbl(txtGrade32.Text)) 
      student(3).dblTestScores(3) = ValidInput(CDbl(txtGrade33.Text)) 
      student(3).dblTestScores(4) = ValidInput(CDbl(txtGrade34.Text)) 

      For Each i As StudentRecord In student 
       For Each d As Double In i.dblTestScores 
        dblGradesTotal3 += d 
       Next 
      Next 

      lblAvg3.Text = CStr(dblGradesTotal3/intMAX_TESTS) 
     Catch ex As Exception 
      MessageBox.Show("Be sure to enter a valid numeric score") 
     End Try 

     Try 
      'Get grades for fifth student 
      student(4).dblTestScores(0) = ValidInput(CDbl(txtGrade40.Text)) 
      student(4).dblTestScores(1) = ValidInput(CDbl(txtGrade41.Text)) 
      student(4).dblTestScores(2) = ValidInput(CDbl(txtGrade42.Text)) 
      student(4).dblTestScores(3) = ValidInput(CDbl(txtGrade43.Text)) 
      student(4).dblTestScores(4) = ValidInput(CDbl(txtGrade44.Text)) 

      For Each i As StudentRecord In student 
       For Each e As Double In i.dblTestScores 
        dblGradesTotal4 += e 
       Next 
      Next 

      lblAvg4.Text = CStr(dblGradesTotal4/intMAX_TESTS) 
     Catch ex As Exception 
      MessageBox.Show("Be sure to enter a valid numeric score") 
     End Try 

     Try 
      'Get grades for sixth student 
      student(5).dblTestScores(0) = ValidInput(CDbl(txtGrade50.Text)) 
      student(5).dblTestScores(1) = ValidInput(CDbl(txtGrade51.Text)) 
      student(5).dblTestScores(2) = ValidInput(CDbl(txtGrade52.Text)) 
      student(5).dblTestScores(3) = ValidInput(CDbl(txtGrade53.Text)) 
      student(5).dblTestScores(4) = ValidInput(CDbl(txtGrade54.Text)) 

      For Each i As StudentRecord In student 
       For Each f As Double In i.dblTestScores 
        dblGradesTotal5 += f 
       Next 
      Next 

      lblAvg5.Text = CStr(dblGradesTotal5/intMAX_TESTS) 
     Catch ex As Exception 
      MessageBox.Show("Be sure to enter a valid numeric score") 
     End Try 
    End Sub 

    Private Sub mnuFileOpen_Click(sender As Object, e As EventArgs) Handles mnuFileOpen.Click 

    End Sub 

    Private Sub mnuFileSave_Click(sender As Object, e As EventArgs) Handles mnuFileSave.Click 

    End Sub 

    Private Sub mnuFilePrint_Click(sender As Object, e As EventArgs) Handles mnuFilePrint.Click 

    End Sub 

    Private Sub mnuFileExit_Click(sender As Object, e As EventArgs) Handles mnuFileExit.Click 

     Me.Close() 
    End Sub 

    Private Sub mnuReportClear_Click(sender As Object, e As EventArgs) Handles mnuReportClear.Click 

    End Sub 

    Private Sub mnuHelpAbout_Click(sender As Object, e As EventArgs) Handles mnuHelpAbout.Click 

     MessageBox.Show("This contains information regarding the Student Test Scores Application") 
    End Sub 

    Private Sub btnCalc_Click(sender As Object, e As EventArgs) Handles btnCalc.Click 

     CalcAverage() 
    End Sub 

    Public Function ValidInput(ByVal score As Double) As Double 

     If score >= 0 And score <= 100 Then 
      Return (score) 
     Else 
      Return MessageBox.Show("Please enter a valid test score between 0 and 100") 
     End If 
    End Function 

    Sub ImportNames() 

     student(0).strStudent = txtStudent0.Text 
     student(1).strStudent = txtStudent1.Text 
     student(2).strStudent = txtStudent2.Text 
     student(3).strStudent = txtStudent3.Text 
     student(4).strStudent = txtStudent4.Text 
     student(5).strStudent = txtStudent5.Text 
    End Sub 
End Class 
+1

为了更好地得到社区的回应,我建议您更具体地了解什么是工作和什么不是,包括任何错误消息,并将代码修剪到相关部分。 http://stackoverflow.com/help/how-to-ask – 2014-11-03 05:49:45

回答

1

欢迎来到SO。将来,请仅发布相关代码,而不是所有内容。在这种情况下,相关代码将会是Try-Catch块之一,如果您得到的分数和平均分数不是全部加上代码的其余部分。

在任何情况下,如果不确切地知道你所看到的是什么,我认为你的平均值出现不正确的原因是因为你计算它们的方式。例如:

For Each i As StudentRecord In student 
    For Each f As Double In i.dblTestScores 
     dblGradesTotal5 += f 
    Next 
Next 

外层循环将遍历student数组中的所有结构。

内部循环会将该学生的所有分数相加。

然后你去找下一个学生......并把所有学生的总分加到前面学生的总分上。

你只需要一个循环,为该学生的分数。你已经知道数组中的结构的指标,所以这个:

For Each f As Double In student(5).dblTestScores 
    dblGradesTotal5 += f 
Next 

,这一行:

lblAvg5.Text = CStr(dblGradesTotal5/intMAX_TESTS) 

会给你平均为学生。

一些更小的事情要考虑。

  1. 您的Try-Catch块每次都做同样的事情。重构代码到一个方法(Sub),并保存你的手指和键盘:)

  2. 在你ValidInput功能,您所指定的返回类型为Double,但在你的Else块返回MessageBox.Show。我甚至不确定会编译,但VB.NET不像C#那么挑剔。无论如何,在Else中返回一个表示错误(-1会很好)的双精度值,并在调用ValidInput的方法中弹出消息框。

输入验证实例

验证用户输入是至关重要的,其良好的,你这样做。在编程中有一句老话 - “永远不要相信用户的输入。”

您当前的方法面临的挑战是您要根据验证结果返回两项中的一项,并且只能从方法返回一种类型(除非使用参数out)。

通常,在尝试转换类型时,我倾向于使用TryParse,因为它将为转换(解析)是否成功以及解析out参数(第二个参数)的结果返回布尔值, 。如果转换失败,这可以防止丑陋的运行时错误。另外,CDbl函数是Visual Basic(.NET之前版本)的一个延续,并且通常认为使用内置的.NET转换运算符会更好。要做到这一点是如下

方式一:

Dim score As Double 

If Double.TryParse(txtGrade50.Text, score) AndAlso (score >= 0 And score <= 100) Then 
    student(5).dbltTestScores(0) = score 
Else 
    MessageBox.Show("Please enter a valid test score between 0 and 100") 
End If 

注意,在上述If语句中使用AndAlso - 这提供了短路逻辑。如果TryParse失败,则不会评估其他任何内容。

上述缺点是现在你有很多代码要重复。另一个缺点是,在将其分配给数组之前,您正在评估输入权限,并且没有给出用户输入错误的任何指示。

我建议在将值分配给结构数组之前验证所有输入 - 这样您可以告诉用户哪些值是错误的,他们可以纠正它并再次尝试。

这里重要的是确保数据是正确的(在要求的范围内)之前你处理它。其他任何事情都有很大的潜力,很快就会变得非常丑陋和混乱。

最后的注意事项 - 在.NET中,匈牙利表示法通常不被认为是最佳实践(即,dblGradesTotal5是匈牙利表示法的一个例子 - 在这种表示法中,您预先给出了一个变量名称和类型)。简单的gradesTotal5是正常的。

+0

非常感谢您的帮助。我更新了我的所有代码,并且平均值现在可以正常工作。我一直无法弄清楚如何使ValidInput函数正常工作。即使之前的工作,我宁愿学习正确的代码方式,所以我真的很感激你的反馈。 Public Function ValidInput(ByVal score As Double)As Double If score> = 0 and score <= 100 Then Return(score) Else Return MessageBox.Show(“请输入0到100之间的有效测试分数”) End If End Function – cccstudent 2014-11-04 00:43:43

+0

我需要添加,你已经提到要使用-1。我在Return中添加了-1和-1(-1),但在两种情况下都将其作为一个值并用它来计算平均值。所以我应该澄清一下,我不理解如何使用-1,或者如果我应该使用函数中的其他内容来验证数字范围内的输入,如果输入了不正确的数据,将给用户一个消息框。 – cccstudent 2014-11-04 00:55:21

+0

@cccstudent - 我今晚晚些时候回家看看并回答。 – Tim 2014-11-04 01:20:01