2017-06-20 93 views
0

我想寫一個C++程序,從文本文件中讀取輸入,並使用十點分級比例分配成績,然後在屏幕上打印結果。 我覺得我的問題可能是函數deriveGrade中的if else語句,而不是遞增枚舉,他們似乎在總結增量。任何幫助將不勝感激,謝謝。從文件如何避免這些if else else複合語句?

#include <iostream> 
#include <string> 
#include <iomanip> 
#include <cmath> 
#include <fstream> 

using namespace std; 
int deriveGrade(double avarage); 
enum letter_grade { A, B, C, D, F }; 

namespace tenPoint 
{ 
    letter_grade deriveGrade(double avarage); 
    char grade; 
} 

using namespace tenPoint; 

int main() 
{ 
    string name; 
    double average; 

    ifstream inData; // Is the variable for input data from the file. 

    inData.open("student_status.txt", ios::in); 

    while (!inData.eof()) 
    { 

     getline(inData, name); 
     inData >> average; 
     inData.ignore(); 
     grade = ::deriveGrade(average); 

     cout << name << " " << average << " " << char(grade) << endl; 

    } 

    inData.close(); 

    return 0; 
} 


int deriveGrade(double average) 
{ 


    if (average >= 90) 
    { 
     grade = static_cast<letter_grade>(grade + 65); 
    } 
    else if (average >= 80 && average < 90) 
    { 
     grade = static_cast<letter_grade>(grade + 1); 
    } 
    else if (average >= 70 && average < 80) 
    { 
     grade = static_cast<letter_grade>(grade + 2); 
    } 
    else if (average >= 60 && average < 70) 
    { 
     grade = static_cast<letter_grade>(grade + 3); 
    } 
    else if (average <= 50) 
    { 
     grade = static_cast<letter_grade>(grade + 4); 
    } 
    else 
    { 
     cout << "Invalid entry." << endl; 
    } 

    return grade; 
} 

輸入:

李四,約翰K.

93.2

安德魯斯,蘇珊S.

84.7

夢露,瑪麗蓮

75.1

加斯頓,阿瑟C.

62.8

哈波,瓊妮Y.

42.7

生薑,弗雷德T.

95.8

程序輸出:

DOE,約翰K. 93.2甲

安德魯斯,蘇珊S. 84.7乙

門羅,瑪麗蓮75.1 d

加斯,亞瑟C. 62.8ģ

Harpo,Joanie Y. 42.7 K

Ginger,Fred T. 95.8 012

按任意鍵繼續。 。 。

+0

自修復我的代碼請求以來的脫離主題。用你所有的警告和調試信息編譯你的代碼(例如'g ++ -Wall -Wextra -g'和[GCC](http://gcc.gnu.org/)...)然後**使用調試器**(例如'gdb')一步一步地運行程序並查詢其內部狀態,從而瞭解發生了什麼。 –

+0

[這樣的東西應該可以工作](http://coliru.stacked-crooked.com/a/9db9ae1fc75bc11d),idk爲什麼你有這個函數的多個聲明和多個不同返回類型的命名空間,這只是令人困惑。 – Borgleader

+0

查看匿名命名空間。我想你會得到你想要得到的東西,而不必在之後立即使用using語句。 – user4581301

回答

2

你的程序的邏輯很奇怪,但一些常見的話可以不加深地加入到你的任務中。

注意的是,雖然使用if... else陳述一個個像

if (average >= 90) 
{ 
    grade = static_cast<letter_grade>(grade + 65); 
} 
else if (average >= 80 && average < 90) 
{ 
    grade = static_cast<letter_grade>(grade + 1); 
} 
... 

沒有必要檢查average < 90else分支後average >= 90發現假的。所以至少代碼可以更短:

int deriveGrade(double average) 
{ 
    if (average >= 90) 
    { 
     grade = static_cast<letter_grade>(grade + 65); 
    } 
    else if (average >= 80) 
    { 
     grade = static_cast<letter_grade>(grade + 1); 
    } 
    else if (average >= 70) 
    { 
     grade = static_cast<letter_grade>(grade + 2); 
    } 
    else if (average >= 60) 
    { 
     grade = static_cast<letter_grade>(grade + 3); 
    } 
    else if (average <= 50) 
    { 
     grade = static_cast<letter_grade>(grade + 4); 
    } 
    else // check here! Invalid interval is for values between 50 and 60? 
    { 
     cout << "Invalid entry." << endl; 
    } 

    return grade; 
} 

但是,這並不是顯着的改善....更好的做一個公式,使用單獨的語句與分配grade = ...

UPDATE:

還有一評論。如果你知道不可接受值的區間,首先要檢查它(所有其他計算前):

int deriveGrade(double average) 
{ 
    // check the correctness of argument first 
    if (average > 50 && average < 60) 
    { 
     cout << "Invalid entry." << endl; // notification 
     return grade; // previous value 
         // also consider returning special value for error case 
    } 
    // calculate value for grade 
    grade = ... 
    // return updated value 
    return grade; 
} 

節「爲等級計算值」是你,而寫這部分代碼記住:

  • 三元操作操作對於一個特殊情況是有用的,例如grade = (average >= 90)? 65 : floor(100 - average)/10;

  • 使用全局值(如grade)的功能是不好的做法,以及使基於邏輯的假設是全局變量的初始值是正確的

0

的原因是因爲你加入到您的grade變量而不清除它,所以前面的操作結果將在deriveGrade中繼續。 我的建議是刪除名稱空間中的全局char grade;,在deriveGrade中使用局部變量,在main中使用不同的局部變量。

如果你看看你的功能代碼,grade只會添加65(如果你的等級高於90,那麼它就會產生一個ASCII碼'A')。然而,每一個後續添加都會假設這個添加已經發生。如果你確保每個其他的都不依賴於前面的if或else代碼,那麼你的代碼應該更加正確。

char deriveGrade(double average) 
    if(average > 90.0) 
    { 
     return 'A'; 
    } 
    else if(average > 80.0) 
    { 
     return 'B'; 
    } 
    ... 

該解決方案消除甚至需要在使用你這麼好聽創建枚舉您deriveGrade 一個更好的替代品使用grade變量是:

enum letter_grade : char 
{ 
    A = 'A', B = 'B', C = 'C', D = 'D', F = 'F' 
}; 

,它允許你通過一個(char)letter_grade來在枚舉表示和字符之間進行交換(您的deriveGrade將改爲返回letter_grade)。