Function return nothing with multiple files? - c++

When I run one file, it works perfectly. Then I separate 3 file: header, main, function from that file. It aslo works but return nothing. Here the code:
File Header: printStudent.h
//Header.h
#ifndef PRINTSTUDENT_H_INCLUDED
#define PRINTSTUDENT_H_INCLUDED
void read ();
#endif
File Function: readFileCSV.cpp . It read and print from my .csv file
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string.h>
#include <algorithm>
#define student 1000
using namespace std;
void read (){
ifstream readFileCSV;
readFileCSV.open("studentEn.csv");
if(!readFileCSV.is_open()) {cout << "ERROR: File can't be opened or it doesn't exist" << endl;};
string aMSSV[student];
string aname[student];
string abirthDay[student];
string aaddress[student];
string MSSV;
string name;
string birthDay;
string address;
int countStudent = 0;
while(readFileCSV.good()) {
getline(readFileCSV, MSSV, ',');
getline(readFileCSV, name, ',');
getline(readFileCSV, birthDay, ',');
getline(readFileCSV, address, '\n');
int lengthAddress = address.length();
char charAddress[lengthAddress];
strcpy(charAddress, address.c_str());
char newCharAddress[lengthAddress-2];
for(int i = 0 ; i < lengthAddress-2 ; i++){
newCharAddress[i] = charAddress[i+1];};
string address(newCharAddress, lengthAddress - 2);
aMSSV[countStudent] = MSSV;
aname[countStudent] = name;
abirthDay[countStudent] = birthDay;
aaddress[countStudent] = address;
countStudent ++;
};
countStudent = countStudent - 1;
cout << "..................................................STUDENT..........................................................." << endl;
cout << setw(5) << left << "STT";
cout << setw(25) << left << "MSSV";
cout << setw(25) << left << "Name";
cout << setw(25) << left << "Date of Birth";
cout << left << "Address";
cout << endl;
cout << "...................................................................................................................." << endl;
for(int i = 0 ; i < countStudent ; i++){
cout << setw(5) << left << i + 1;
cout << setw(25) << left << aMSSV[i];
cout << setw(25) << left << aname[i];
cout << setw(25) << left << abirthDay[i];
cout << left << aaddress[i];
cout << endl;
}
readFileCSV.close();
}
File main:
#include <iostream>
#include "printStudent.h"
using namespace std;
int main(){
void read ();
return 0;
}
Help me why it's return nothing and give me a solution how can i make it works? Thanks!

int main(){
void read ();
return 0;
}
It is a function declaration in main a.k.a. forward declaration. Any expression that starts with a type or void is a declaration. It is a local declaration, thus it doesn't conflict with the globally declared function read.
To call the function do it so
int main(){
read ();
return 0;
}

Related

Getting average age of students and youngest student's name

I'm having some trouble with getting the average age of all students including getting the youngest student's name outputted. The output is supposed to come from a function call I wrote called ageCalc(...).
main.cpp
#include <iostream>
#include <fstream>
#include <iomanip>
#include "Student1.h"
#include "Student2.h"
#include "ageCalc.h"
using namespace std;
const int SIZE = 100;
int main()
{
ifstream inFile;
inFile.open("C:\\COMSC200\\a2data.input", ios::in|ios::binary);
// Open the input file – if it fails to open, display an error message and terminate
if(!inFile.is_open())
{
cout << "Unable to open file!";
return 1;
}
else
{
cout << "File successfully open!\n\n";
}
// Use a pointer array to manage all the created student variables.
Student1 **ptrArr = new Student1 *[SIZE];
Student1 s;
int total = 0;
// read the first input record
inFile.read(reinterpret_cast<char *> (&s), sizeof(s));
while(!inFile.eof())
{
// dynamically allocate space for new student variable
ptrArr[total] = new Student1;
// populate the student variable from the input
*ptrArr[total] = s;
total++;
// read the next input record
inFile.read(reinterpret_cast<char *> (&s), sizeof(s));
}
Student2 *st = new Student2[SIZE];
for(int i = 0; ptrArr[i]; i++)
{
for(char fn: ptrArr[i]->first_name)
st[i].fn += fn;
st[i].mi = ptrArr[i]->middle_int[0];
for(char ln: ptrArr[i]->last_name)
st[i].ln += ln;
st[i].cc = ptrArr[i]->campus_code;
for(char sID: ptrArr[i]->student_ID)
st[i].sID += sID;
st[i].age = atoi(ptrArr[i]->age);
}
cout << "First Name" << setw(9)
<< "MI" << setw(15)
<< "Last Name" << setw(17)
<< "Campus Code" << setw(16)
<< "Student ID" << setw(15)
<< "Age" << endl;
cout << "===================================================================================" << endl;
for(int j = 0; st[j].age != 0; j++)
{
cout << st[j].fn << setw(8);
cout << st[j].mi << " ";
cout << st[j].ln << setw(2);
cout << st[j].cc << " ";
cout << st[j].sID << setw(16);
cout << st[j].age << " " << endl;
}
Student2 *y;
int avg = ageCalc(&st, y);
cout << "Average student age is: " << avg << " years." << endl;
cout << "Youngest student is: " << arr[i]->fn << " " << arr[i]->mi << " " << arr[i]->ln << endl;
for(int x = 0; ptrArr[x]; x++)
{
delete ptrArr[x];
}
delete [] st;
inFile.close();
return 0;
}
ageCalc.cpp
#include "Student2.h"
using namespace std;
int ageCalc(Student2 *arr[], Student2 *&y)
{
int i = 0, sum = 0, index = 0, avg;
while(arr[i] != nullptr)
{
sum = arr[i]->age + sum;
i++;
if(arr[i]->age < arr[index]->age)
{
index = i;
}
}
y = arr[index];
avg = sum / i;
return avg;
}
Student1.h
#ifndef STUDENT1_H_
#define STUDENT1_H_
#include <iostream>
using namespace std;
struct Student1
{
char first_name[10];
char middle_int[10];
char last_name[20];
char campus_code;
char student_ID[8];
char age[3];
};
#endif
Student2.h
#ifndef STUDENT2_H_
#define STUDENT2_H_
#include <iostream>
#include <string>
using namespace std;
struct Student2
{
string fn;
char mi;
string ln;
char cc;
string sID;
short int age;
};
#endif
ageCalc.h
#ifndef AGECALC_H_
#define AGECALC_H_
#include "Student2.h"
int ageCalc(Student2 *[], Student2 *&);
#endif

Using virtual functions with classes and constructors to print book info

I'm at the very last step for this project, and I'm stuck on what to do. The project is to take an input file containing book info, like this:
A Book on C
Al Kelly and Ira Pohl
Addison-Wesley, Fifth Edition 1998.
0201183994
C How to Program
Paul Deitel and Harvey Deitel
Prentice Hall Sixth Edition 2010
0136123562
And then print it using several options. I'll put all the code here so you can compile and see what each option does. I'm having trouble with option 5, specifically. For option 5, I need to:
Input more information on each book. I'm required to have two subclasses, InfoBookRecord containing the price and author biography, and TypeBookRecord containing the book genre.
Print the new information using virtual functions. I thought it made sense to make the virtual function in the class ListRecords, but the grading key seems to imply I should be using them for the two subclasses InfoBookRecord and TypeBookRecord. I can't think of any way to do that.
header.h:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <fstream>
#include <algorithm>
using namespace std;
#define TABLE_SIZE 200
class BookRecord{
public:
BookRecord(string input_title, string input_author, string input_publisher, int input_isbn);
string getTitle();
string getAuthor();
string getPublisher();
int getISBN();
private:
string title;
string author;
string publisher;
int isbn;
};
class InfoBookRecord: public BookRecord {
public:
InfoBookRecord(string input_title, string input_author, string input_publisher, int input_isbn, double input_price, string input_authorBio) : BookRecord(input_title,input_author,input_publisher,input_isbn) {
price=input_price;
authorBio=input_authorBio;}
double getPrice();
string getAuthorBio();
private:
double price;
string authorBio;
};
class TypeBookRecord: public BookRecord {
public:
TypeBookRecord(string input_title, string input_author, string input_publisher, int input_isbn, string input_genre) : BookRecord(input_title,input_author,input_publisher,input_isbn){
input_genre.resize(15);
genre=input_genre;}
string getGenre();
private:
string genre;
};
class ListRecords{
public:
ListRecords(char filename[]);
void insertBookInfo(BookRecord record);
//virtual void printBookInfo(int bookISBN);
void printBookInfo(int bookISBN);
void printListByISBN();
void printListByTitle();
BookRecord ** books;
InfoBookRecord ** books2;
TypeBookRecord ** books3;
int line_num;
int k;
string garbage;
};
// problem here
/*
class extraListRecords: public ListRecords{
public:
extraListRecords();
void printBookInfo(int bookISBN){
cout << "testing 1 2 3 " << endl;
}
};*/
BookRecord.cpp:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <fstream>
#include <algorithm>
#include "header.h"
using namespace std;
#define TABLE_SIZE 200
BookRecord::BookRecord(string input_title, string input_author, string input_publisher, int input_isbn){
title=input_title;
author=input_author;
publisher=input_publisher;
isbn=input_isbn;
}
string BookRecord::getTitle() {return title;}
string BookRecord::getAuthor() {return author;}
string BookRecord::getPublisher() {return publisher;}
int BookRecord::getISBN() {return isbn;}
double InfoBookRecord::getPrice() {return price;}
string InfoBookRecord::getAuthorBio() {return authorBio;}
string TypeBookRecord::getGenre() {return genre;}
ListRecords.cpp:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <fstream>
#include <algorithm>
#include "header.h"
using namespace std;
#define TABLE_SIZE 200
ListRecords::ListRecords(char filename[]){
ifstream input(filename);
assert(("Error: File does not exist.", input != NULL));
string line;
line_num=0;
while (getline(input,line)){
line_num++;
}
//go back to beginning of file
input.clear();
input.seekg(0, ios::beg);
char lines[TABLE_SIZE][TABLE_SIZE];
int i=0;
// load lines of file into array
while (i < line_num) {
input.getline(lines[i],TABLE_SIZE);
i++;
}
input.close();
books = new BookRecord*[TABLE_SIZE];
books2 = new InfoBookRecord*[TABLE_SIZE];
books3 = new TypeBookRecord*[TABLE_SIZE];
k=0;
for(i=0;i<line_num;i+=5){
// check for duplicate entries
int test=0;
for(int j=0;j<i/5;j++){
if(books[j]->getISBN() == atoi(lines[i+3])){
cout << "Found a duplicate ISBN... ignoring entry " << lines[i+3] << endl;
test=1;
}
}
// if not a duplicate entry, add to array
if(test==0){
int the_price;
cout << "Please enter price of " << lines[i] << ": " << endl;
cin >> the_price;
getline(cin,garbage);
string the_authorBio;
cout << "Please enter author bio of " << lines[i] << ": ";
cin >> the_authorBio;
getline(cin,garbage);
string the_genre;
cout << "Please enter the book genre of " << lines[i] << ": ";
cin >> the_genre;
getline(cin,garbage);
*(books2+k) = new InfoBookRecord(lines[i],lines[i+1],lines[i+2],atoi(lines[i+3]),the_price,the_authorBio);
*(books3+k) = new TypeBookRecord(lines[i],lines[i+1],lines[i+2],atoi(lines[i+3]),the_genre);
*(books+k) = new BookRecord(lines[i],lines[i+1],lines[i+2],atoi(lines[i+3]));
k++;
}
else
i+=5;
}
}
void ListRecords::insertBookInfo(BookRecord record){
line_num+=5;
*(books+k) = new BookRecord(record.getTitle(),record.getAuthor(),record.getPublisher(),record.getISBN());
k++;
}
void ListRecords::printBookInfo(int bookISBN){
int found=0;
for(int i=0;i<k;i++){
if(books[i]->getISBN() == bookISBN){
if(to_string(books[i]->getISBN()).length()==9)
cout << endl << books[i]->getTitle() << endl << books[i]->getAuthor() << endl << books[i]->getPublisher() << endl << "0" << books[i]->getISBN() << endl;
if(to_string(books[i]->getISBN()).length()==10)
cout << endl << books[i]->getTitle() << endl << books[i]->getAuthor() << endl << books[i]->getPublisher() << endl << books[i]->getISBN() << endl;
found=1;
break;
}
}
if(found==0)
cout << "The record you requested was not found in the list." << endl;
}
bool compare_by_isbn(BookRecord* x,BookRecord* y) { return (x->getISBN() < y->getISBN()); }
bool compare_by_title(BookRecord* x,BookRecord* y) { return (x->getTitle() < y-> getTitle()); }
void ListRecords::printListByISBN(){
sort(books, books + k, compare_by_isbn);
printf(" %-22s %-22s %-17s %s\n", "Title", "Author", "Publisher", "ISBN");
cout << string(22, '-') << " " << string(22, '-') << " " << string(22, '-') << " " << string(10, '-') << endl;
for(int i=0;i<k;i++){
if(to_string(books[i]->getISBN()).length()==9)
printf("%-22.22s %-22.22s %-22.22s 0%d\n", books[i]->getTitle().c_str(), books[i]->getAuthor().c_str(), books[i]->getPublisher().c_str(), books[i]->getISBN());
if(to_string(books[i]->getISBN()).length()==10)
printf("%-22.22s %-22.22s %-22.22s %d\n", books[i]->getTitle().c_str(), books[i]->getAuthor().c_str(), books[i]->getPublisher().c_str(), books[i]->getISBN());
}
}
void ListRecords::printListByTitle(){
sort(books, books + k, compare_by_title);
printf(" %-22s %-22s %-17s %s\n", "Title", "Author", "Publisher", "ISBN");
cout << string(22, '-') << " " << string(22, '-') << " " << string(22, '-') << " " << string(10, '-') << endl;
for(int i=0;i<k;i++){
if(to_string(books[i]->getISBN()).length()==9)
printf("%-22.22s %-22.22s %-22.22s 0%d\n", books[i]->getTitle().c_str(), books[i]->getAuthor().c_str(), books[i]->getPublisher().c_str(), books[i]->getISBN());
if(to_string(books[i]->getISBN()).length()==10)
printf("%-22.22s %-22.22s %-22.22s %d\n", books[i]->getTitle().c_str(), books[i]->getAuthor().c_str(), books[i]->getPublisher().c_str(), books[i]->getISBN());
}
}
main.cpp:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <fstream>
#include <algorithm>
#include "header.h"
using namespace std;
#define TABLE_SIZE 200
int main(int argc, char* argv[]){
char filename[50];
cout << "Enter the name of a file to load:" << endl;
cin >> filename;
ListRecords listrecords(filename);
while(true){ // looping for the selection menu
int selection, n;
cout << "Please select a menu option:\n1) Insert a book record into the list\n2) Print information of a book with a given ISBN number\n3) Print the list of books sorted by ISBN\n4) Print the list of books sorted alphabetically by title\n5) Print the books also with info on price, author biography, and genre.\n6) Quit the program" << endl;
cin >> selection;
if(cin.fail()){ // make sure input is a digit
cout << "Invalid selection. Quitting program..." << endl;
break;
}
if(selection==1){
string in_title;
string in_author;
string in_publisher;
int in_isbn;
string junk;
getline(cin, junk);
cout << endl << "Please enter a title: ";
getline(cin, in_title);
cout << "Please enter an author: ";
getline(cin, in_author);
cout << "Please enter a publisher: ";
getline(cin, in_publisher);
cout << "Please enter an ISBN: ";
cin >> in_isbn;
BookRecord new_record(in_title, in_author, in_publisher, in_isbn);
listrecords.insertBookInfo(new_record);
cout << endl << "The record has been added to the list." << endl;
cout << endl << endl;
}
if(selection==2){
int in_isbn;
cout << endl << "Please enter ISBN number: " << endl;
cin >> in_isbn;
listrecords.printBookInfo(in_isbn);
cout << endl << endl;
}
if(selection==3){
cout << endl;
listrecords.printListByISBN();
cout << endl << endl;
}
if(selection==4){
cout << endl;
listrecords.printListByTitle();
cout << endl << endl;
}
if(selection==5){
int in_isbn;
cout << endl << "Please enter ISBN number: " << endl;
cin >> in_isbn;
cout << endl << "List of books also with info on price and author biography: " << endl;
cout << endl << endl;
// problem here
// extraListRecords extras;
//ListRecords *bookextras= &extras;
// bookextras->printBookInfo(in_isbn);
cout << endl << "List of books also with info on genre: " << endl;
}
if(selection==6){
cout << endl << "Program terminating normally..." << endl;
break;
}
} // end of while(true) loop
return 0;
};
Makefile:
LFLAGS = -Wno-write-strings -std=c++11
CFLAGS = -Wno-write-strings -std=c++11 -c
myprogam: main.o BookRecord.o ListRecords.o
g++ $(LFLAGS) -o myprogram main.o BookRecord.o ListRecords.o header.h
main.o: main.cpp header.h
g++ $(CFLAGS) main.cpp
BookRecord.o: BookRecord.cpp header.h
g++ $(CFLAGS) BookRecord.cpp
ListRecords.o: ListRecords.cpp header.h
g++ $(CFLAGS) ListRecords.cpp
clean:
rm *.o
rm myprogram
I commented out the two parts giving me trouble. One is at the end of header.h, and the other is near the end of main.cpp.
When I try to make this, I get the error
main.cpp:(.text+0x4c7): undefined reference to `extraListRecords::extraListRecords()'
collect2: error: ld returned 1 exit status
make: *** [myprogam] Error 1
I've tried a few other attempts at that subclass with the virtual function, such as adding the initialization of book2 and book3 to the body of its constructor, so writing its constructor as extraListRecords(char filename[]) :ListRecords(filename){ / the chunk of code in ListRecords.cpp above around line 55 / }
Thanks a bunch for the help!
You need to provide the constructor definition for extraListRecords
class extraListRecords: public ListRecords {
public:
extraListRecords() = default;
// ^^^^^^^^^^
};
I figured it out. The problem was pretty silly. I just forgot to flush the buffer between cin on an integer and getline.
cin and getline skipping input
The virtual function was completely fine as extraListRecords(char filename[]): ListRecords(filename){;} as the constructor in the header.

Floating Point Exception while reading from file

the program should read from 2 files (author.dat and citation.dat) and save them into a map and set;
first it reads the citationlist without problem, then it seems to properly read the authors and after it went through the whole list (author.dat) a floating point exception arises .. can't quite figure out why
seems to happen in author.cpp inside the constructor for authorlist
author.cpp:
#include <fstream>
#include <iostream>
#include "authors.h"
using namespace std;
AuthorList::AuthorList(char *fileName) {
ifstream s (fileName);
int idTemp;
int nrTemp;
string nameTemp;
try {
while (true){
s >> idTemp >> nrTemp >> nameTemp;
cout << idTemp << " " << nrTemp << " " << nameTemp << " test_string";
authors.insert(std::make_pair(idTemp,Author(idTemp,nrTemp,nameTemp)));
if (!s){
cout << "IF-CLAUSE";
throw EOFException();
}
cout << "WHILE-LOOP_END" << endl;
}
} catch (EOFException){}
}
author.h:
#ifndef CPP_AUTHORS_H
#define CPP_AUTHORS_H
#include <iostream>
#include <map>
#include <string>
#include "citations.h"
class Author {
public:
Author (int id, int nr, std::string name) :
articleID(id),
authorNR(nr),
authorName(name){}
int getArticleID() const {
return articleID;
}
std::string getAuthorName() const {
return authorName;
}
private:
int articleID;
int authorNR;
std::string authorName;
};
class AuthorList {
public:
AuthorList(char *fileName);
std::pair<std::multimap<int,Author>::const_iterator, std::multimap<int,Author>::const_iterator> findAuthors(int articleID) {
return authors.equal_range(articleID);
}
private:
std::multimap<int,Author> authors;
};
#endif //CPP_AUTHORS_H
programm.cpp:
#include <iostream>
#include <cstdlib>
#include "citations.h"
#include "authors.h"
#include "authorCitation.h"
using namespace std;
int main(int argc, char *argv[]){
CitationList *cl;
AuthorList *al;
//check if argv array has its supposed length
if (argc != 4){
cerr << "usage: programm article.dat citation.dat author.dat";
return EXIT_FAILURE;
}
//inserting citation.dat and author.dat in corresponding lists (article.dat not used)
cl = new CitationList(argv[2]);
al = new AuthorList(argv[3]);
try {
AuthorCitationList *acl;
acl->createAuthorCitationList(al,cl);
acl->printAuthorCitationList2File("authorcitation.dat");
} catch (EOFException){
cerr << "something went wrong while writing to file";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
All files:
https://drive.google.com/file/d/0B734gx5Q_mVAV0xWRG1KX0JuYW8/view?usp=sharing
I am willing to bet that the problem is caused by the following lines of code:
AuthorCitationList *acl;
acl->createAuthorCitationList(al,cl);
You are calling a member function using an uninitialized pointer. I suggest changing the first line to:
AuthorCitationList *acl = new AuthorCitationList;
Add any necessary arguments to the constructor.
While you are at it, change the loop for reading the data also. You have:
while (true){
s >> idTemp >> nrTemp >> nameTemp;
cout << idTemp << " " << nrTemp << " " << nameTemp << " test_string";
authors.insert(std::make_pair(idTemp,Author(idTemp,nrTemp,nameTemp)));
if (!s){
cout << "IF-CLAUSE";
throw EOFException();
}
cout << "WHILE-LOOP_END" << endl;
}
When you do that, you end up adding data once after the end of line has been reached. Also, you seem to have the last line in the wrong place. It seems to me that it should be outside the while loop.
You can use:
while (true){
s >> idTemp >> nrTemp >> nameTemp;
// Break out of the loop when reading the
// data is not successful.
if (!s){
cout << "IF-CLAUSE";
throw EOFException();
}
cout << idTemp << " " << nrTemp << " " << nameTemp << " test_string";
authors.insert(std::make_pair(idTemp,Author(idTemp,nrTemp,nameTemp)));
}
cout << "WHILE-LOOP_END" << endl;
You can simplify it further by using:
while (s >> idTemp >> nrTemp >> nameTemp){
cout << idTemp << " " << nrTemp << " " << nameTemp << " test_string";
authors.insert(std::make_pair(idTemp,Author(idTemp,nrTemp,nameTemp)));
}
cout << "WHILE-LOOP_END" << endl;

error C2228: left of '.printStats' must have class/struct/union

So I recently decided to pick up programming again and went with C++. Tried to make an adventurer class, but I seem to be running into some trouble. Here are my files:
Adventurer.h:
#ifndef __Adventurer_H_INCLUDED__ //if Adventurer.h hasn't been included yet...
#define __Adventurer_H_INCLUDED__ //#define this so the compiler knows it has been included
class Adventurer
{
private:
int hp, mp, str, agi, magic, armour;
public:
Adventurer(){}
void printStats();
}
#endif
Adventurer.cpp:
#include <iostream>
#include "Adventurer.h"
Adventurer::Adventurer()
{
hp = 50;
mp = 25;
str = 5;
agi = 5;
magic = 5;
armour = 5;
}
void Adventurer::printStats()
{
cout << "HP = " << hp << "\n\n";
cout << "MP = " << mp << "\n\n";
cout << "str = " << str << "\n\n";
cout << "agi = " << agi << "\n\n";
cout << "magic = " << magic << "\n\n";
cout << "armour = " << armour << "\n\n";
}
RPG_Game.cpp:
// my first program in C++
#include <iostream>
#include <string>
#include "Adventurer.h"
;using namespace std;
int main()
{
cout << "Hello Adventurer! What is your name? \n";
string advName;
cin >> advName;
cout << "\nYour name is " << advName << "!";
Adventurer *adv = new Adventurer();
cout << adv.printStats();
delete adv;
system(pause);
}
Let's look at the errors in your code
First, in your Adventurer.h, put a semicolon (;) after the class.
Next, in that same class, you have
Adventurer(){}
change this to
Adventurer();
Then, in your RPG_Game.cpp , change
cout << adv.printStats();
to
adv->printStats() ;
When using pointers, you need to use -> and not .
And lastly,
system(pause);
should be
system( "pause" );
Now, try running your code.
Also, you might find this helpful.

reading double from a binary file (into a class) - decimals do not show

having trouble displaying the decimals after reading the data.
As the title says.. here are some code snippets.
the header for the student 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];
};
student header:
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 &);
};
Student implementation (inherited the above)
#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();
}
the main
#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);
}
output:
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
the problem is in this line near the bottom. it won't display any decimal points. any help is greatly appreciated.
setprecision(4) << node->getValue().getMarks()[i]
i can supply any other files which may be helpful. i'm just hoping my mistakes are somewhere in the main.
You've given us a lot of code to wade through for a simple
formatting issue, but I don't see where you tell the output
stream how you want the floating point values formatted. The
default formatting is defined so that it will result in
something readable for all possible values, but in practice,
it's never what you want for any particular set of values
(except maybe in log files or for serialization purposes). In
your case (and in a lot of smaller programs), you could probably
get by with just setting the floating point format to fixed:
ofile.setf( std::ios_base::fixed, std::ios_base::floatfield );
More generally, the best practice would be to define a
manipulator for the different semantic values you need: e.g.:
std::ostream&
mark( std::ostream& dest )
{
dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
dest.precision( 2 );
return dest;
}
You can then simply write:
ofile << ... << mark << node->getValue().getMarks()[i] << ...
Note, however, that both the format option and the precision are
sticky; they will remain set until changed. In any significant
code, it is a good practice to reset them to what they were
before.