2010-10-26 123 views
1

我差不多已经完成了这个任务,但是有两件事让我在代码中陷入困境。 当我查询用户的测试分数时,如果分数不在0-100范围内,我不想接受它,然后告诉他们为什么要求另一个输入。 我也想在他们的平均分数旁边打印他们平均的字母等级。 由于某些原因,当我尝试检查以确保输入的分数在0-100之内时,我的If逻辑语句不起作用。 此外,我不知道如何获得打印字母等级,但我没有得到任何错误输出,所以我认为我在正确的轨道上。我认为我可以主要在我的while循环中使用指针来检查数字是否在0-100的范围内。我将不胜感激。 这里是我的代码:验证用户输入

import java.text.DecimalFormat; 
import java.util.Scanner; 
public class GradeReport 
{ 
String name; 
int score1, score2, score3; 
double average; 
String grade; 
public GradeReport() //creates the first constructor 
{ 
    Scanner sc = new Scanner (System.in); 

    System.out.println ("Enter student's name: "); 
    name = sc.nextLine(); 

    System.out.println ("Enter first grade: "); //try while loops to get grade in between 0-100 
    score1 = sc.nextInt(); 
    while 
     (score1 <0 || score1 > 100); 
    System.out.println("please enter a grade 0-100"); //checks that score is inclusive 1-100 

    System.out.println ("Enter second grade: "); 
    score2 = sc.nextInt(); 
    while 
     score2 <0 || score2 > 100; 
    System.out.println("please enter a grade 0-100");//checks that score is inclusive 1-100 

    System.out.println ("Enter third grade: "); 
    score3 = sc.nextInt(); 
    while 
     score3 <0 || score3 >100; 
    System.out.println("please enter a grade 0-100");//checks that score is inclusive 1-100 
} 
public GradeReport (String v1, int v2, int v3, int v4) 
{ 
    name = v1; //these are to initialize the variables so that I don't get null for the second set of results. 
    score1 = v2; 
    score2 = v3; 
    score3 = v4; 
} 
public void calculateAvg() 
{ 
    average = (double)((score1 + score2 + score3)/3.0); 


} 
public String calculateGrade() 
{ 
    if (average >= 90) 
    grade = "A"; 
    else if (average >= 80) 
    grade = "B"; 
    else if (average >= 70) 
    grade = "C"; 
    else if (average >= 60) 
    grade = "D"; 
    else 
    grade = "F"; 
    return grade; 
} 

public String toString() 
{ 
    DecimalFormat fmt = new DecimalFormat ("0.00"); //to format average to 2 decimal places 
    String gradeReport = name + "\n " + Double.toString(score1) + "\t" + Double.toString(score2)+ "\t" + Double.toString(score3) + "\n" + fmt.format(average) + grade; 
    return gradeReport; 
} 

public static void main (String[] args) 
{ 
    GradeReport gr1 = new GradeReport(); 
    GradeReport gr2 = new GradeReport("Col Een", 76, 76, 75); 
    gr1.calculateAvg(); 
    gr1.calculateGrade(); 
    gr2.calculateAvg(); 
    gr2.calculateGrade(); 
    System.out.println(gr1); 
    System.out.println(gr2); 
} 

} 

回答

3

一些评论...

压痕

请尽量与你的缩进风格一致。它使你的代码更容易阅读。

空白

小心你如何管理你的空白。当你阅读一本书或一本杂志或一个网页时,空白空间用于分隔想法 - 段落,章节等。同样,空白空间应该用来分隔你的功能或功能内的想法。例如:

 
void f1() 
{ 
    do(); 
    domore(); 
} 


void f2() 
{ 
    doAnotherThing(); 
    andYetAnother(); 
} 


void f3() 
{ 
    do1(); 
    do2(); 

    do3(); 
    do4(); 
} 

注意,很容易看到,有3个独立的功能,第三功能有东西它做两个独立的团体 - DO1()和D02()从DO3分离()和do4()带有空白空间,直观地表明do1()和do2()与do3()和do4()有相似之处,并且与有些不同3.

如果没有意义,请随时忽略:)(但我建议你阅读一本基本的视觉设计书)

大括号

在所有条件块中使用大括号是一个不错的主意 - 它使得块非常清楚块的开始和结束。例如,

 
if(condition) 
    line1; 
    line2; 

 
if(condition) 
{ 
    line1; 
    line2; 
} 

在第一种情况不同,一号线将执行当且仅当该条件为真,但2号线将评估不管是什么 - 缩进被欺骗。在第二种情况下,当且仅当条件为真时,line1和line2才会执行。

在第一种情况下,意图不明确 - 原始开发人员是否搞垮了压痕(对于迂腐,忽略使用缩进来管理循环的语言)?或者他/他忘记了大括号?如果第一种情况被写成如下,我们就知道答案了:

 
if(condition) { 
    line1 
} 
    line2 

当然,如果压痕是通过文件一致,下面的代码的意图是明确的,以及:

 
if(condition) 
    line1 
line2 

无限循环

注意结尾,你有

 
while 
     (score1 <0 || score1 > 100); 
分号

尾随分号结束块。如果score1无效,则循环将永远不会退出。

编译

我不知道该

 
while 
     score2 <0 || score2 > 100; 

是有效的代码。你应该在这个条件下放置parens。再次,您还遇到了尾随分号的无限循环问题。

取得的成绩

当你问成绩,你的代码现在看起来像

 
score = readLine() 
while(...) 
    System.out.println(...) 

这意味着你读取用户输入,然后进入循环,在您打印的消息。请记住:循环从while开始的位置开始,因此在第一次迭代之后,读取输入永远不会发生。您需要读取用户每次迭代循环写入的值。

 
score = readline() 
while(score is invalid) 
{ 
    print error 
    score = readline() 
} 

变量命名

忽略这一部分,如果它没有任何意义,现在 - 认为这是一个不好的介绍以后的东西,你会学习。

如果你有选择,你应该总是有意义地给你的变量命名。该GradeReport构造函数有4个变量,其目的完全是不明的,如果你没有访问源代码:

 
public GradeReport (String v1, int v2, int v3, int v4) 

你可以使用相同的名称为变量作为类插槽,你可以区分this关键字。如果我们先插入this在构造函数中的所有类变量,并留下其余不变,就变成:

 
public GradeReport (String v1, int v2, int v3, int v4) 
{ 
    this.name = v1; //these are to initialize the variables so that I don't get null for the second set of results. 
    this.score1 = v2; 
    this.score2 = v3; 
    this.score3 = v4; 
} 

,如果我们替换“名称” V1 ...

 
public GradeReport (String name, int v2, int v3, int v4) 
{ 
    this.name = name; //these are to initialize the variables so that I don't get null for the second set of results. 
    this.score1 = v2; 
    this.score2 = v3; 
    this.score3 = v4; 
} 

,然后用score1替换v2 ...

 
public GradeReport (String name, int score1, int v3, int v4) 
{ 
    this.name = name; //these are to initialize the variables so that I don't get null for the second set of results. 
    this.score1 = score1; 
    this.score2 = v3; 
    this.score3 = v4; 
} 
+0

风格提示+1和变量命名 – jball 2010-10-26 20:16:26

+0

谢谢atk。我同意jball的观点,你做了一个非常好的彻底的工作来解释所有这些。 – Josh 2010-10-27 02:02:14

1

一些你的代码看起来不可编译的我,但是那一边,考虑以下三行代码之间的区别:相比

if (score2 <=0) 

while (score1 <0 || score1 > 100) 

if (score3 <=0) 

我想你会发现你的问题的一部分。为了验证,可以考虑以下模式:

do { 
    //collect input 
} while (something that's false if input is invalid); 
+0

啊。所以你建议使用do while循环而不是while循环。我很难学习循环,所以感谢您的帮助。我改变了我的代码,但我认为我改变了它可能比以前更加错误的东西。 – Josh 2010-10-26 19:06:01

+0

上面显示的循环是您在代码中应该具有的语法,包括围绕代码请求用户输入的'{}'和围绕表达式的'()'评估末尾的'while'关键字之后的输入的循环。 – jball 2010-10-26 19:15:24