2010-10-26 428 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