我有一项建立学生考试成绩申请的任务 我有一个结构来保存一个学生的名字,一个数组可以容纳5个考试成绩,以及一个平均分数。我为6名学生创建了一系列结构。用户输入通过文本框设置。我需要计算每个学生的平均值。 作业要求: 应用程序应具有存储的结构:名称(字符串),测试分数(5个双精度数组)和平均值(双精度数)。它应该有一个由6个结构变量组成的数组来匹配6个学生。它应该允许用户输入每个学生的数据,并计算每个学生的平均测试分数。用户需要能够在文件等中保存,读取和打印数据。
不应接受低于0或高于100的分数。
我已经阅读了几篇帖子,但无法解决现有帖子,并且花了最近两天的时间尝试解决。现在我没有得到正确的平均值 我还需要能够打印和检索信息,但我首先要解决这个问题。我在学生的最大计数中尝试了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
答案 0 :(得分: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)
会给你那个学生的平均分。
还需要考虑一些小问题。
您的Try-Catch
块每次都做同样的事情。将代码重构为方法(Sub
)并保存手指和键盘:)
在ValidInput
函数中,您将返回类型指定为Double
,但在Else
块中,您将返回MessageBox.Show
。我甚至不确定会编译,但VB.NET并不像C#那样挑剔。在任何情况下,在Else
中返回表示错误的双精度数(-1会很好)并在调用ValidInput
的方法中弹出消息框。
输入验证示例
验证用户输入至关重要,而且您正好这样做。在编程中有一句老话 - &#34;永远不要相信用户的输入。&#34;
您当前的方法面临的挑战是,您尝试返回两项中的一项,具体取决于验证结果,并且您只能从方法中返回一种类型(除非您使用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
请注意在上述AndAlso
语句中使用If
- 这提供了短路逻辑。如果TryParse
失败,则无法评估任何其他内容。
上面的缺点是,现在你需要重复很多代码。另一个缺点是,在将输入分配给阵列之前,您正在评估输入,并且您没有给出用户输入错误的任何指示。
我建议在将值分配给结构数组之前验证所有输入 - 这样你就可以告诉用户哪些值是错误的,他们可以纠正它并再试一次。
这里重要的是确保在处理之前数据是正确的(在要求的限制范围内)。其他任何东西都很有可能很快变得非常丑陋和混乱。
最后的注意事项 - 在.NET中,匈牙利表示法通常不被认为是最佳实践(即,dblGradesTotal5
是匈牙利表示法的一个示例 - 您可以在其中添加一个类型的变量名称)。一个简单的gradesTotal5
是正常的。