Aim: • Design a solution to a problem from a partially complete framework. • Gai
ID: 3733750 • Letter: A
Question
Aim:
• Design a solution to a problem from a partially complete framework.
• Gain some experience writing a database application in C++.
• Using binary I-O in C++ programs.
Instructions:
To receive 2 marks for the demo you must complete Step-1 and demonstrate it to your lab supervisor in
week-3. The week-4 submission instructions are provided at the end of this document. Please read the Ass1
Q/As on moodle regularly in case suggestions are provided or changes are made to the assignment
specification.
You are to write a student enrollment system for a university. For each student the system is to keep the
following information:
a) First Name
b) Last Name
c) Number of Subjects
d) Subjects (Codes; Status, Marks;};
In the Ass1 folder you will find an incomplete implementation of the enrollment system and a datafile called
ass1.txt for testing the program. Examine the data file to get a feel for the data in this system. You may
assume that the file contains no errors. All work for this assignment should be done in the ass1.cpp file. Do
not modify main.cpp or ass1.h. To compile on linux/unix: g++ main.cpp ass1.cpp. To run on linux: ./a.out.
The file: “How to compile with DevCpp.pdf” explains how to compile all the files on DevC++.
(Marking: Step 1 is worth 4 marks (including the demo). Steps 2 and 3 are worth 3 marks each.)
Step 1 Implement the functions: ReadFile(), FindRecord(), DisplayRecord() and PrintRecord() according
to the pseudo code provided. Information and example code on reading and writing text files can be
found in the C++ Guide in the Wk 1 Lecture folder. Test that your program can correctly load the
array from the data file and display records on the screen. Example output is given below:
13 records read
Commands Available:
d - Display Record
u - Update Record
q - Quit the program
Command: d
Enter student number: 4734455
Student No. 4734455
First Name Kieren
Last Name Legrande
Subjects:
CSCI104 Provisional 65
IACT123 Enrolled 67
CSCI121 Enrolled 98
CSCI251 –Assignment 1 2
Step 2 Implement the UpdateRecord() and SaveFile() functions and test your program to ensure that it
can amend student records and save all records to the file ass1.txt.
Command: u
Enter student number: 4734455
Student No. 4734455
First Name Kieren
Last Name Legrande
Subjects:
CSCI104 Provisional 65
IACT123 Enrolled 67
CSCI121 Enrolled 98
Enter subject code: CSCI104
Select status or mark (s/m): s
Select new status
e: enrolled
p: provisional
w: withdrawn
Status: e
Record 4734455 Updated.
Step 3 Requires implementation of binary file I-O into the program. If you are unfamiliar with binary
file I-O, information on this can be found in BinaryFiles.pdf and the C++ Guide available in the
Lecture Notes folder. To implement binary file I-O follow these steps.
(a) Add four more private functions to ass1.cpp:
bool ReadTextFile(char Filename[]); //reads text data from file to gRecs[] array
bool WriteTextFile(char Filename[]); //writes text data from gRecs[] to file
bool ReadBinaryFile(char Filename[]); //reads binary data from file to gRecs[] array
bool WriteBinaryFile(char Filename[]); //writes binary data from gRecs[] to file
To do this, copy the code in the ReadFile() and SaveFile() functions to ReadTextFile and
WriteTextFile() respectively. Modify this code so that it uses the passed filename and return
false if the file or path is not found when opened. ReadBinaryFile() and WriteBinaryFile()
should read/write the binary contents of gRecs[] to the passed filename (see lecture notes:
BinaryFiles.pdf) (Note: the binary file should store the number of records followed by the
record data.)
Rewrite the ReadFile() function so that it uses the above functions and attempts to read the
binary file (named in global cBinaryFileName). If this fails, it then attempts to read the text
file (named in global cTextFileName) and then writes the binary file. If ReadFile() fails to
read the binary file and the text file it should print an appropriate error message and exit.
(b) Add one more private function named:
void WriteBinaryRecord(char Filename[], int Pos);
This function should:
open the binary file (named in global cBinaryFileName)
seek() to the appropriate record at Pos
write the record to the binary file
close the file
Then alter the UpdateRecord() function so that it also updates the binary file by calling the
above function.
(c) Modify the SaveFile() function so that it attempts to write the gRecs[] array to the binary file.
If this fails it then attempts to write the data to the text file.
(d) Test your program to ensure that the binary data is being appropriately saved to the file.
Explanation / Answer
ass1.cpp
#include <iostream>
#include <fstream>
#include <string.h>
#include <stdlib.h>
using namespace std;
// ============== Constants ==========================================
char cTextFileName[] = "ass1.txt";
char cBinaryFileName[] = "ass1.dat";
const int cMaxRecs = 100;
const int cMaxChars = 30;
const int cMaxSubjects = 8;
// ============= User Defined types ==================================
enum StatusType{eEnrolled,eProvisional,eWithdrawn};
struct SubjectType{ char Code[8]; StatusType Status; int Mark;};
struct StudentRecord{
long StudentNo;
char FirstName[cMaxChars];
char LastName[cMaxChars];
int NumSubjects;
SubjectType Subjects[cMaxSubjects];
};
// ============= Global Data =========================================
StudentRecord gRecs[cMaxRecs];
int gNumRecs=0;
// ============= Private Function Prototypes =========================
void PrintRecord(int i);
int FindRecord(long StudentNum);
int findSubjectCode(char subjectCode[8],int studentRecordId);
bool ReadTextFile(char Filename[]); //reads text data from file to gRecs[] array
bool WriteTextFile(char Filename[]); //writes text data from gRecs[] to file
bool ReadBinaryFile(char Filename[]); //reads binary data from file to gRecs[] array
bool WriteBinaryFile(char Filename[]); //writes binary data from gRecs[] to file
void WriteBinaryRecord(char Filename[], int Pos);
// ============= Public Function Definitions =========================
void ReadFile()
{// Reads data file into array
if(ReadBinaryFile(cBinaryFileName)){
cout<<"successfully read binary file ";
}else{
cout<<"Unable to read binary file.. Reading Text file.. ";
if(ReadTextFile(cTextFileName)){
cout<<"Read text file ";
}else{
cout<<"Unable to read text file and binary file.. ";
cout<<"exiting.. ";
exit(EXIT_FAILURE);
}
}
}
void DisplayRecord()
{// Displays specified record on screen
long studentNumber;
int i;
cout<< "Enter student number: ";
cin>> studentNumber;
i= FindRecord(studentNumber);
if (i==-1){
cout<<"Record not found";
}
else{
PrintRecord(i);
}
}
void SaveFile()
{// Writes array to files
int i,j;
if(WriteBinaryFile(cBinaryFileName)){
cout<<"written to binary file ";
}
else{
cout<<"Unable to write to binary file... Attempting to write to text file... ";
//Saving data to text file
ofstream fout;
fout.open("ass1.txt");
if(!fout.good()){
cout<<"Cant find text data file for writing ! ";
exit(EXIT_FAILURE);
}
for (i=0;i<gNumRecs;i++){
fout<<gRecs[i].StudentNo<<endl;
fout<<gRecs[i].FirstName<<" "<<gRecs[i].LastName<<endl;
fout<<gRecs[i].NumSubjects<<endl;
for(j=0;j<gRecs[i].NumSubjects;j++){
fout<<gRecs[i].Subjects[j].Code<<" "<<gRecs[i].Subjects[j].Status<<" "<<gRecs[i].Subjects[j].Mark<<endl;
}
fout<<endl;
}
fout.close();
cout<<"Records Saved to text file ";
}
}
void UpdateRecord()
{
int Pos=0;
long studentNumber;
int studentRecordId; //Stores the index of gNumRecs
char subjectCode[8];
char statusOrMark;
int newMark;
int newStatus;
int foundSubjectCode;
cout<< "Enter student number: ";
cin>> studentNumber;
studentRecordId=FindRecord(studentNumber);
if(studentRecordId==-1){
cout<<"Record not found ! ";
}
else{
PrintRecord(studentRecordId); //Displaying student record
cout<<" Enter subject code : ";
cin>> subjectCode;
foundSubjectCode=findSubjectCode(subjectCode,studentRecordId);
if(foundSubjectCode!=-1){
cout<<" change status(s) or mark(m)? :";
cin>> statusOrMark;
if(statusOrMark=='m'){
cout<<" New mark:: ";
cin>>newMark;
cout<<" Changing "<< gRecs[studentRecordId].Subjects[foundSubjectCode].Mark << " to ==> " << newMark<<endl;
gRecs[studentRecordId].Subjects[foundSubjectCode].Mark=newMark;
cout<<"changed mark";
}else if (statusOrMark== 's'){
cout<<" New status:: 0-eEnrolled 1-eProvisional 2-eWithdrawn ::";
cin>> newStatus;
cout<<" Changing "<< gRecs[studentRecordId].Subjects[foundSubjectCode].Status << " to ==> " << newStatus <<endl;
gRecs[studentRecordId].Subjects[foundSubjectCode].Status=(StatusType)newStatus; //Check
cout<<"changed status";
}
//TODO
WriteBinaryRecord(cBinaryFileName,studentRecordId);
SaveFile();
}
else{
cout<<"subject code not found";
}
}
}
// ============= Private Function Definitions =========================
void PrintRecord(int i)
{ // Prints record i on screen
int j;
cout<<endl<<"Student Record::"<<endl;
cout<<"Student No. " <<gRecs[i].StudentNo<<endl;
cout<<"Name "<< gRecs[i].FirstName<<" ";
cout<< gRecs[i].LastName<<endl;
cout<<"Number of Subjects " << gRecs[i].NumSubjects<<endl;
cout<<"Subjects: ";
for (j=0;j<gRecs[i].NumSubjects;j++){
cout<<" " <<gRecs[i].Subjects[j].Code;
switch(gRecs[i].Subjects[j].Status){
case eEnrolled:
cout<<" Enrolled";
break;
case eProvisional:
cout<<" Provisional";
break;
case eWithdrawn:
cout<<" Withdrawn";
break;
}
cout<<" " <<gRecs[i].Subjects[j].Mark<<endl;
}
cout<<endl;
}
int FindRecord(long StudentNo)
{// returns index of matching record or -1 if not found
int i;
for (i=0;i<gNumRecs;i++){
if (gRecs[i].StudentNo == StudentNo){
return i;
}
}
return -1;
}
int findSubjectCode(char subjectCode[8],int studentRecordId)
{ // finds subject code
int j;
int i=studentRecordId;
for (j=0;j<gRecs[i].NumSubjects;j++){
if(strcmp(gRecs[i].Subjects[j].Code,subjectCode)==0){
cout<<"found subject code with index ::" << j;
return j;
}
}
return -1;
}
bool ReadTextFile(char Filename[]){
//reads text data from file to gRecs[] array
int subjectStatus;
ifstream fin;
fin.open(Filename);
if(!fin.good()){
cout<<"Cant find text data file ! ";
return 0;
}
int j;
int i= 0;
char NumSubjectsString;
fin>> gRecs[i].StudentNo;
while (!fin.eof()){
fin>> gRecs[i].FirstName;
fin>> gRecs[i].LastName;
fin>> gRecs[i].NumSubjects;
for (j=0;j<gRecs[i].NumSubjects;j++){
fin>>gRecs[i].Subjects[j].Code;
fin>>subjectStatus;
switch(subjectStatus){
case 0:
gRecs[i].Subjects[j].Status=eEnrolled;
break;
case 1:
gRecs[i].Subjects[j].Status=eProvisional;
break;
case 2:
gRecs[i].Subjects[j].Status=eWithdrawn;
break;
}
fin>>gRecs[i].Subjects[j].Mark;
}
i++;
fin>>gRecs[i].StudentNo;
}
gNumRecs=i;
cout<< i<< " Records read"<<endl;
fin.close();
return 1;
}
bool WriteTextFile(char Filename[]){
//writes text data from gRecs[] to file
int i,j;
ofstream fout;
fout.open(Filename);
if(!fout.good()){
cout<<"Cant find text data file for writing ! ";
return 0;
}
for (i=0;i<gNumRecs;i++){
fout<<gRecs[i].StudentNo<<endl;
fout<<gRecs[i].FirstName<<" "<<gRecs[i].LastName<<endl;
fout<<gRecs[i].NumSubjects<<endl;
for(j=0;j<gRecs[i].NumSubjects;j++){
fout<<gRecs[i].Subjects[j].Code<<" "<<gRecs[i].Subjects[j].Status<<" "<<gRecs[i].Subjects[j].Mark<<endl;
}
fout<<endl;
}
fout.close();
cout<<"Records Saved ";
return 1;
}
bool ReadBinaryFile(char Filename[]){ //reads binary data from file to gRecs[] array
int subjectStatus;
int numberOfRecords;
ifstream fin;
fin.open(Filename,ios::in|ios::binary);
if(!fin.good()){
cout<<"Cant find binary data file ! ";
return 0;
}
int j;
int i= 0;
char NumSubjectsString;
fin.read((char*)&gNumRecs, sizeof(int)); // write number of records
fin.read((char*)gRecs, sizeof(StudentRecord) * gNumRecs); // write records
cout<< gNumRecs<< " Records read from binary file"<<endl;
fin.close();
return 1;
}
bool WriteBinaryFile(char Filename[]){ //writes binary data from gRecs[] to file
int i,j;
ofstream fout;
fout.open(Filename,ios::out|ios::binary);
if(!fout.good()){
cout<<"Cant find text data file for writing ! ";
return 0;
}
fout.write((char*)&gNumRecs, sizeof(int)); // write number of records
fout.write((char*)gRecs, sizeof(StudentRecord) * gNumRecs); // write records
fout.close();
cout<<"Records Saved in binary file ";
return 1;
}
void WriteBinaryRecord(char Filename[], int Pos){
ofstream fout;
fout.open(Filename,ios::out|ios::binary);
if(!fout.good()){
cout<<"Cant find text data file for writing ! ";
exit(1);
}
fout.seekp(sizeof(int) + Pos * sizeof(StudentRecord), ios::beg); // seek to position
fout.write((char*)&gRecs[Pos], sizeof(StudentRecord)); // write record
}
main.cpp
#include <iostream>
#include <cctype>
#include "ass1.h"
using namespace std;
void PrintMenu();
int main(){
char Command;
ReadFile();
PrintMenu();
do{
cout << "Command: ";
cin >> Command;
Command=tolower(Command);
switch (Command)
{
case 'u':
UpdateRecord();
break;
case 'd':
DisplayRecord();
break;
case 'm':
PrintMenu();
break;
case 'q':
break;
default:
cerr << "Illegal Command ";
PrintMenu();
}
} while (Command != 'q');
SaveFile();
return 0;
}
void PrintMenu(){
cout << "Commands Available: ";
cout << " d - Display Record ";
cout << " u - Update Record ";
cout << " m - Print Menu ";
cout << " q - Quit the program ";
}
ass1.h
#ifndef ass1_h
#define ass1_h
void ReadFile();
void SaveFile();
void DisplayRecord();
void UpdateRecord();
void AddRecord();
#endif
ass1.txt
7453842
Gregory Harrison
4
CSCI104 0 100
IACT111 2 100
INFO112 0 75
CSCI321 0 89
7545349
Quentin Resnick
3
CSCI104 0 55
IACT101 1 76
INFO101 0 78
4639649
Owen Porter
4
CSCI321 0 66
CSCI333 0 34
IACT303 0 66
INFO303 0 77
4734455
Kieren Legrande
3
CSCI104 1 65
IACT123 0 67
CSCI121 0 98
3974537
Uriah VanDenBerg
3
CSCI104 1 65
IACT121 2 44
MATH122 0 66
8564833
Erica Forsythe
4
CSCI104 1 76
MATH222 2 87
CSCI124 0 98
STAT122 0 76
9111265
Yolanda Zefirovic
4
CSCI111 0 66
CSCI104 2 56
CSCI123 0 78
IACT124 0 70
3882534
Xavier Williams
5
CSCI104 0 80
CSCI121 1 66
CSCI222 0 54
MATH212 2 65
CSCI232 0 87
3424426
Salvatore Torelli
2
CSCI104 2 77
CSCI123 0 46
9956348
Anna Baker
4
CSCI104 1 65
CSCI108 0 45
CSCI144 0 50
STAT123 0 55
9467737
Minh Nguyen
4
CSCI111 0 66
CSCI104 0 69
CSCI222 0 76
MATH123 0 56
9456257
Imran Jabeil
3
CSCI112 1 67
CSCI333 0 77
IACT111 0 85
9846475
Christopher Davenport
4
CSCI212 0 65
CSCI213 1 50
CSCI222 0 55
IACT202 0 77
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.