2

读取数据后无法显示小数。

正如标题所说..这里有一些代码片段。

学生 obj 的标题

class StudentRecordData
{
protected:
   double Marks[MAX_COURSES];
   unsigned int Age;
   unsigned int ID;
   unsigned int CourseCount;
   char FirstName[LEN_FN];
   char LastName[LEN_FN];
   Course  Courses[MAX_COURSES];
};

学生头:

class Student : public StudentRecordData {

public:
    double *getMarks();
    unsigned int getAge();
    unsigned int getID();
    unsigned int getCourseCount();
    char *getFirstName();
    char *getLastName();
    Course *getCourses();
    double getAverage();

    int operator < (Student &);
    int operator < (const char &);
};

学生实现(继承上述)

#include "Student.h"
#include <iostream>
#include <cstring>
using namespace std;

double *Student::getMarks() {
    return Marks;
}

unsigned int Student::getAge() {
    return Age;
}

unsigned int Student::getID() {
    return ID;
}

unsigned int Student::getCourseCount() {
    return CourseCount;
}

char *Student::getFirstName() {
    return FirstName;
}

char *Student::getLastName() {
    return LastName;
}

Course *Student::getCourses() {
    return Courses;
}

int Student::operator<(Student &s) {
    int ret = 0;

    int LNRet = strcmp(this->getLastName(), s.getLastName());
    int FNRet = strcmp(this->getFirstName(), s.getFirstName());

    if (LNRet < 0) {
        ret = 1;
    } else if (LNRet == 0) {
        if (FNRet < 0) {
            ret = 1;
        }
    }

    return ret;
}

int Student::operator<(const char &s) {
    cout << "in char *!" << endl;
    int ret = 0;

    return ret;
}

double Student::getAverage() {
    double total = 0.00;
    for (int i = 0; i < (getCourseCount()); i++) {
        total = total + getMarks()[i];
    }
    return total / getCourseCount();
}

主要的

#include "Course.h"
#include "Student.h"
#include "Node.h"
#include "LinkedList.h"
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

int main(void) {
    char input[] = "OOP344.dat";
    char output[] = "OUTPUT.txt";
    Student student;
    LinkedList list;
    Node *node;

    // read in file
    ifstream ifile(input, ios::binary);
    while (!ifile.eof()) {
        ifile.read(reinterpret_cast<char *>(&student), sizeof(Student));

        node = new Node(student);
        list.addNode(node);
    }
    ifile.close();

    list.sort();

    // write to file
    ofstream ofile(output);
    if (ofile.is_open()) {

        for (node = list.getFirstNode(); node; node = list.getNextNode(node)) {
            cout << setw(10) << "Last Name" << setw(12) << "First Name" << setw(5) << "Age" << setw(12) << "Student ID" <<
                    setw(15) << "Course"    << setw(7) << "Mark" << endl;
            cout << setw(10) << "=========" << setw(12) << "==========" << setw(5) << "===" << setw(12) << "==========" <<
                    setw(15) << "======"    << setw(7) << "=====" << endl;
            cout << setw(10) << node->getValue().getLastName()
                 << setw(12) << node->getValue().getFirstName()
                 << setw(5) << node->getValue().getAge()
                 << setw(12) << node->getValue().getID()
                 << setw(22) << node->getValue().getAverage()
                 << endl;

                    int sem, sem_prev;

                    for (int i = 0; i < node->getValue().getCourseCount(); i++) {
                        sem = (int)node->getValue().getCourses()[i].Semester;
                        sem_prev = (int)node->getValue().getCourses()[i-1].Semester;

                        if (!(sem == sem_prev)) {
                            cout << setw(45) << "Sem " << (int)node->getValue().getCourses()[i].Semester << ":"
                                 << setw(7) << node->getValue().getCourses()[i].Name
                                 << setw(7) << setprecision(4) << node->getValue().getMarks()[i] << endl;
                        } else {
                            cout << setw(54) << node->getValue().getCourses()[i].Name
                                 << setw(7) << setprecision(4) << node->getValue().getMarks()[i] << endl;
                        }

                    }

                     cout << endl;
        }
    }
    ofile.close();

    return (0);
}

输出:

Last Name  First Name  Age  Student ID         Course   Mark
 =========  ==========  ===  ==========         ======  =====
   Sakedad        Roya   25      486503                 74.31
                                         Sem 1: APC100     69
                                                EAC150     92
                                                ICA002     76
                                                IOS110     87
                                                IPC144     99
                                         Sem 2: ULI101     62
                                                DBS201     66
                                                IBC233     94
                                                INT222     58
                                                OOP244     67
                                         Sem 3: DBS301     61
                                                INT322     89
                                                SYS366     52
                                                BAC344     80
                                                OOP344     63
                                         Sem 4: DCN455     74

问题出在靠近底部的这条线上。它不会显示任何小数点。任何帮助是极大的赞赏。

  setprecision(4) << node->getValue().getMarks()[i] 

我可以提供任何其他可能有用的文件。我只是希望我的错误主要在某个地方。

4

1 回答 1

2

你给了我们很多代码来解决一个简单的格式化问题,但我看不出你在哪里告诉输出流你希望浮点值如何格式化。定义了默认格式,以便它会导致所有可能值的可读性,但实际上,对于任何特定的值集(可能在日志文件中或用于序列化目的除外),它永远不是您想要的。在您的情况下(以及在许多较小的程序中),您可能只需将浮点格式设置为固定即可:

ofile.setf( std::ios_base::fixed, std::ios_base::floatfield );

更一般地说,最佳实践是为您需要的不同语义值定义一个操纵器:例如:

std::ostream&
mark( std::ostream& dest )
{
    dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
    dest.precision( 2 );
    return dest;
}

然后你可以简单地写:

ofile << ... << mark << node->getValue().getMarks()[i] << ...

但是请注意,格式选项和精度都是粘性的;它们将保持设置直到更改。在任何重要的代码中,将它们重置为之前的状态都是一个好习惯。

于 2013-04-01T20:10:26.510 回答