2013-04-29 102 views
-1

嗨,我开始创建一个程序来计算一个人的GPA并保存该信息供将来参考。我的问题是,我无法弄清楚如何读取保存在.txt文件中的数字,然后将它们存储以便进行GPA计算。这里是未完成的程序的代码和任何帮助将是伟大的C++将txt文件数据转换为双重变量

编辑:.txt文件是这样布局:5.0 3.7 5.0 3.7 5.0 4.0 ...下面是我在程序中的进展,但是当我运行它时,我收到0(不正确)的GPA。不知道词法转换是我的问题,getline()方法还是别的。任何帮助(calculateGPA()方法是麻烦的地方)?

#include <iostream> 
#include <fstream> 
#include <string> 
#include <boost/lexical_cast.hpp> 
using namespace std; 

string newCC, newCG; 
double curGPA; 
char command; 
bool running = 1; 

void calculateGPA(); 
void writeGrades(); 
void mainMenu(); 
void addClass(); 

int main() 
{ 
    while(running) { 
     mainMenu(); 
    } 

    return 0; 
} 

void calculateGPA() 
{ 
    double credit_sum = 0.0, grade_sum = 0.0; 
    double credit, grade; 

    ifstream gReader("grades.txt"); 

    for(int i = 0; ! gReader.eof() ; i++) 
    { 
     string number; 

     getline(gReader , number) ; 

     double dblNumber; 
     try 
     { 
     dblNumber = boost::lexical_cast<double>(number); 
     } 
     catch (boost::bad_lexical_cast const&) 
     { 
       dblNumber = 0; 
     } 

     credit_sum = credit_sum + dblNumber; 
    } 

    ifstream cReader("credits.txt"); 

    for(int i = 0; ! cReader.eof() ; i++) 
     { 
      string number; 

      getline(cReader , number) ; 

      double dblNumber; 
      try 
      { 
      dblNumber = boost::lexical_cast<double>(number); 
      } 
      catch (boost::bad_lexical_cast const&) 
      { 
        dblNumber = 0; 
      } 
      credit_sum = credit_sum + dblNumber; 
     } 

    if(credit_sum == 0.0) { 

     curGPA = 0.0; 
    } 

    curGPA = (grade_sum/credit_sum); 

    cReader.close() ; 
    gReader.close() ; 

}//End calculateGPA 

void writeGrades() 
{ 
    string cToWrite = newCC + "\n"; 
    string gToWrite = newCG + "\n"; 

    ofstream cWriter("credits.txt", ios::app); 
    cWriter << cToWrite; 
    ofstream gWriter("grades.txt", ios::app); 
    gWriter << gToWrite; 

    cWriter.close(); 
    gWriter.close(); 
}//End writeGrades 

void addClass() 
{ 
    cout << "New class' credits?"; cin >> newCC; 
    cout << endl << "New class' grade? (GP)"; cin >> newCG; 
    writeGrades(); 
    cout << "Add another class? (y/n)" << endl; cin >> command; 
    if(command == 'y') 
     addClass(); 
    else mainMenu(); 
}//End addClass 

void mainMenu() 
{ 
    string command; 

    cout << "What would you like to do?" << endl; 
    cout << "(V)iew GPA" << endl; 
    cout << "(A)dd grades" << endl; 
    cout << "(E)xit" << endl; 

    cin >> command; 

    if(command == "v") 
    { 
     calculateGPA(); 
     cout << "Your current GPA is " << curGPA << endl; 
    } 
    else if(command == "a") 
    { 
     addClass(); 
    } 

    else running = 0; 

}//End mainMenu 

回答

0

使用流:

double calculateGPA() { 
    double credit_sum = 0.0, grade_sum = 0.0; 
    double credit, grade; 
    ifstream reader("grades.txt"); 

    while (!reader.eof()) { /* while the file still has numbers to be read */ 
     reader >> credit >> grade; 

     if (reader.fail()) { 
      /* something unexpected happened (read error/formatting error) */ 
      break; 
     } 

     credit_sum += credit; 
     grade_sum += grade; 
    } 

    if(credit_sum == 0.0) { 
     /* avoid divide by zero */ 
     return 0.0; 
    } 

    /* divide the total grade by the total credits */ 
    return grade_sum/credit_sum; 
} 

注:

  • 假设.txt文件只具有数(学分, (空格或 换行符):对于更复杂的格式化,您希望使用scanf或 正则表达式。
  • 返回double而不是float,您通常希望double的精度为 超过float的相对较小的速度和内存优势。
  • 当功能结束时,当读者输出 的范围时,文件将被关闭。 reader.close()是没有必要的,但不会是一个坏 事情就摆在(我只是懒惰。)
+0

感谢您的回复。 .txt文件的格式如下:5.0 3.7 5.0 3.7 5.0 4.0等等。我需要将第一个数字乘以第二个数字并存储该值,然后将第三个数字乘以第四个数字并存储该值,依此类推。我怎么做到这一点(我正在考虑某种循环,但不知道如何) – Techmaster37 2013-04-29 02:55:45

+0

更新了我的答案,以解决我所想*的工作解决方案。根据维基百科,“GPA的计算方法是将学生在特定时间段内获得的成绩点数除以所学的总学分数。”更新的解决方案就是这样。 – 2013-04-29 06:58:29

+0

非常感谢。我在代码中敲了一下,程序运行了,但是它计算的GPA是0.86129。代码中的所有内容对我来说都是有意义的,除了'读者>>信用>>等级';'线。它是如何工作的以及一些可能的替代方案。非常感谢您的帮助 – Techmaster37 2013-04-30 01:01:27

0

看这个功能:http://www.cplusplus.com/reference/cstdlib/atof/

你可以用它来字符串(或字符)被转换成在读成一个双。我想,你希望双,因为成绩是4.0,3.7,3.3,3.0,等

+0

atof(和atoi)不提供任何可靠的方法来检查失败。出于这个原因,如果你想用C方式来做,我会推荐scanf。 – 2013-04-29 02:19:41

0

或者,你可以直接读入一个双。

calculateGPA() 
{ 
    double credit; 
    ... 
    reader >> credit; 
    ... 
} 

而且,在你的WriteGrades功能,为什么你写你的前行,而不是在年底新线(使用ENDL而不是“\ n”)?

+0

感谢您的回复。不知道为什么我这样做,但是我感谢你的评论 – Techmaster37 2013-04-29 02:57:21