Traversing a linked list with a structure inside - c++

So I a linked list of 4 students and inside each node for the linked list is a structure that holds some data about the students. I want to traverse this linked list and print the data inside each of the structures. I can traverse the linked list expect all the data print is 0. Any help would be much appreciated.
#include<stdlib.h>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
using namespace std;
void displayGrades( struct Outer *O);
void calculateGrades(struct Outer *O);
void readGrades( struct Outer *O);
struct Inner{
int id;
string name;
double midterm1;
double midterm2;
double midtermTotal;
double lab_H;
double finalExam;
double total;
};
Inner i1;
struct Outer{
Inner data;
Outer *next;
};
struct Outer o1, o2, o3, o4;
int main()
{
readGrades(&o1);
calculateGrades(&o1);
displayGrades(&o1);
//o1.next = &o2;
/*
readGrades(&o2);
calculateGrades(&o2);
displayGrades(&o2);
//o2.next =&o3;
readGrades(&o3);
calculateGrades(&o3);
displayGrades(&o3);
//o3.next =&o4;
readGrades(&o4);
calculateGrades(&o4);
displayGrades(&o4);
//o4.next =NULL;
*/
Outer *ptro1;
ptro1 = new Outer;
Outer *ptro2;
ptro2 = new Outer;
Outer *ptro3;
ptro3 = new Outer;
Outer *ptro4;
ptro4 = new Outer;
Outer *head=ptro1;
ptro1->next = ptro2;
ptro2->next = ptro3;
ptro3->next = ptro4;
ptro4->next = NULL;
while(head!=NULL) // && i<=2)
{
cout<<"Student ID: "<<head->data.id<<endl;
cout<<"Student Midterm1: "<<head->data.midterm1<<endl;
cout<<"Student Midterm2: "<<head->data.midterm2<<endl;
cout<<"Student Labs and Homework: "<<head->data.lab_H<<endl;
cout<<"Student Final Exam: "<<head->data.finalExam<<endl;
head = head->next;
}
return 0;
}
void readGrades(struct Outer *O){
cout<<"Enter the student's id: "<<endl;
cin>>o1.data.id;
cout<<"Enter the student's midterm #1 grade: ";
cin>>o1.data.midterm1;
cout<<"Enter the student's midterm #2 grade: ";
cin>>o1.data.midterm2;
cout<<"Enter the student's lab and homework grade: ";
cin>>o1.data.lab_H;
cout<<"Enter the student's final exam grade: ";
cin>>o1.data.finalExam;
}
void displayGrades(struct Outer *O){
cout<<"The students final grade is: ";
if(O->data.total>=90)
{
cout<<"A"<<endl;
}
else if(O->data.total<=89 && O->data.total>=80)
{
cout<<"B"<<endl;
}
else if(O->data.total<=79 && O->data.total>=70)
{
cout<<"C"<<endl;
}
else if(O->data.total<=69 && O->data.total<60)
{
cout<<"F"<<endl;
}
}
void calculateGrades(struct Outer *O){
O->data.midtermTotal=(((O->data.midterm1/50)+(O- >data.midterm2/50))/2)*35;
O->data.lab_H=(O->data.lab_H/20)*25;
O->data.finalExam=(O->data.finalExam/100)*40;
O->data.total=O->data.midtermTotal+O->data.lab_H+O->data.finalExam;
//displayGrades();
}

In the below function you need to use O as you are passing it but you are using
o1 which will overwrite every time
void readGrades(struct Outer *O)
{
cout<<"Enter the student's id: "<<endl;
cin>>O->data.id;
cout<<"Enter the student's midterm #1 grade: ";
cin>>O->data.midterm1;
cout<<"Enter the student's midterm #2 grade: ";
cin>>O->data.midterm2;
cout<<"Enter the student's lab and homework grade: ";
cin>>O->data.lab_H;
cout<<"Enter the student's final exam grade: ";
cin>>O->data.finalExam;
}

You should create a constructor that initializes the member variables to 0. Most of compilers do not do that by default.
struct Inner{
Inner() : id(0),midterm1(0),midtermTotal(0), lab_H(0), finalExam(0), total(0)
{
}
int id;
string name;
double midterm1;
double midterm2;
double midtermTotal;
double lab_H;
double finalExam;
double total;
};

Related

if else problem salary formula for loop desire loop user input

asking desire number to become the for loop(how many employee if input is 4 then 4 loop if 3 3 loops), salary formula not working, if else statement for string name to not accept number and vice versa integer to not accept letters. another one of my problem is how can I name the loop for example the question is name hours and rate then the cout should do 1. name hours rate, 2.name hours rate 3.name hours rate... the code is working.. just need some imporvements.
#include <iostream>
#include <cstdlib>
using namespace std;
void displayRules()
{
cout<<"====================="<<endl;
cout<<" EMPLOYEE-SALARY "<<endl;
cout<<"====================="<<endl;
cout<<" "<<endl;
}
int main()
{
char ans;
do
{
system("cls");
displayRules();
struct Employee
{
string name;
double hours;
double rate;
double salary;
Employee *next;
Employee *prev;
};
Employee *head;
head=NULL;
Employee *newEmployee;
Employee *EmpPointer;
Employee *nextEmpPointer;
Employee *prevEmpPointer;
string inpname;
int inpN;
double inphours;
double inprate;
double salary;
salary = (inprate*inphours);
for(int ctr=0; ctr<3; ctr++)
{
cout<<endl;
cout<<"Enter Name: \t\t";
cin>> inpname;
cout<<"Enter # Hours Worked: \t";
cin>> inphours;
if (inphours<0)
{
cout << "Invalid Input! Program Stopped. ";
return 0;
}
cout<<"Enter Rate per Hour: \t";
cin>> inprate;
if (inprate<0)
{
cout << "Invalid Input! Program Stopped. ";
return 0;
}
newEmployee = new Employee;
newEmployee->name=inpname;
newEmployee->hours=inphours;
newEmployee->rate=inprate;
newEmployee->next=NULL;
if (head==NULL)
head=newEmployee;
else
{
EmpPointer=head;
while (EmpPointer->next)
EmpPointer=EmpPointer->next;
EmpPointer->next=newEmployee;
}
}
cout<<endl;
Employee *displayPointer;
displayPointer=head;
system("cls");
cout<<"------------------------------------------------------------"<<endl;
cout<<" =Summary of PAYROLL= "<<endl;
cout<<"------------------------------------------------------------"<<endl;\
cout<<"Employee Name\t"<<"# Hours Worked\t"<<"Rate/Hour\t"<<"Salary\t"<<endl;
while (displayPointer)
{
cout<<displayPointer->name<<"\t\t";
cout<<displayPointer->hours<<"\t\t";
cout<<displayPointer->rate<<"\t\t";
cout<<displayPointer->salary<<endl;
displayPointer=displayPointer->next;
}
cout<<"------------------------------------------------------------"<<endl;
cout<<endl;
cout << "Would you like to run the program again? (Y/N) ";
cin>>ans;
}
while (ans == 'y' or ans == 'Y');
return 0;
}
Note: The salary wasn't being calculated so I fix that.
I broke your code into small functions in which each function only does one thing and one thing only (Single Responsibility Principle).
Also, I introduce function templates that allows you to reuse a function when you provide the type.
Finally, the code is missing a clean up of pointers to prevent memory leaks. Each time you use the keyword new to obtain a pointer to memory, you need later to check if the pointer contains null and if doesn't then use the keyword delete to free that memory, else you end with memory leaks in your code. Therefore, I leave you with the task to write the function that should iterate your employee list and free the memory to prevent memory leaks.
I hope this is useful.
#include <iostream>
#include <cstdlib>
using namespace std;
struct Employee {
string name;
double hours;
double rate;
double salary;
Employee *next;
Employee *prev;
};
void displayRules() {
cout<<"====================="<<endl;
cout<<" EMPLOYEE-SALARY "<<endl;
cout<<"====================="<<endl;
cout<<" "<<endl;
}
// Here we create a function template to make this code more reusable
template <typename T>
T consoleInput(const std::string& prompt) {
T value;
std::cout << prompt;
std::cin >> value;
return value;
}
// Lets create our own assert to exit the app.
void assertGreaterEqualThanZero(const double value, const std::string& prompt){
if (value < 0) {
cout << prompt;
exit(1);
}
}
// Small functions that do one thing only makes coding easy to debug
Employee* createEmployee(string name, int hours, int rate) {
Employee *newEmployee = new Employee;
newEmployee->name=name;
newEmployee->hours=hours;
newEmployee->rate=rate;
newEmployee->salary = (rate * hours);
newEmployee->next=NULL;
// You need to set and maintain ->prev
// if you are thinking on using a double linked list
// else remove it from the structure since is unused.
return newEmployee;
}
// This is a helper function to add new employees to a list
Employee* addToEmployeeList(Employee* list, Employee* newEmployee){
if (list==NULL) {
list = newEmployee;
} else {
Employee *EmpPointer = list;
while (EmpPointer->next)
EmpPointer=EmpPointer->next;
EmpPointer->next=newEmployee;
}
return list;
}
// The only purpose of this function is to print the list provided
void printEmployeList(Employee* employeeList){
Employee *currentEmployee = employeeList;
system("cls");
cout<<"------------------------------------------------------------"<<endl;
cout<<" =Summary of PAYROLL= "<<endl;
cout<<"------------------------------------------------------------"<<endl;
while (currentEmployee){
cout<<"Employee Name\t"<<"# Hours Worked\t"<<"Rate/Hour\t"<<"Salary\t"<<endl;
cout<<currentEmployee->name<<"\t\t";
cout<<currentEmployee->hours<<"\t\t";
cout<<currentEmployee->rate<<"\t\t";
cout<<currentEmployee->salary<<endl;
cout<<"------------------------------------------------------------"<<endl;
currentEmployee=currentEmployee->next;
}
}
// I leave you with this piece that is missing.
// TODO: create function that delete each employee in the list,
// then deletes the list in order to prevent memory leaks
int main() {
char ans;
do {
system("cls");
displayRules();
Employee *employeeList;
employeeList=NULL;
for(int ctr=0; ctr<3; ++ctr) {
// Lets declare and instantiate when we need it.
string name = consoleInput<string>("Enter Name: \t\t");
// No need to use inp (as inphours) in front of your variables
// It makes it harder to read. Just put hours as a name.
double hours = consoleInput<double>("Enter # Hours Worked: \t");
assertGreaterEqualThanZero(hours, "Invalid Input! Program Stopped.");
double rate = consoleInput<double>("Enter Rate per Hour: \t");
assertGreaterEqualThanZero(rate, "Invalid Input! Program Stopped. ");
Employee *newEmployee = createEmployee(name, hours, rate);
employeeList = addToEmployeeList(employeeList, newEmployee);
}
cout << endl;
printEmployeList(employeeList);
cout << "Would you like to run the program again? (Y/N) ";
cin>>ans;
} while (ans == 'y' or ans == 'Y');
return 0;
}

Filling struct with void function

I was trying to fill and show the data of a struct using void functions, the problem is that it looks that there is a problem once I try to fill the struct "persona" with the void function "llenar", it does not fill it, once I show the data (with "mostrar") in the console it looks like it is empty, this problem does not appear when I do not use the void function "llenar".
#include <iostream>
using namespace std;
struct persona
{
string nombre; //elementos
float fisica;
float quimica;
float matematica;
float ponderado;
};
void llenar (persona P)
{
cout<<"nombre: ";
cin>>P.nombre;
cout<<" nota fisica: ";
cin>>P.fisica;
cout<<" nota quimica: ";
cin>>P.quimica;
cout<<" nota matematica: ";
cin>>P.matematica;
}
void mostrar(persona P)
{
cout<<"nombre: ";
cout<<P.nombre<<endl;
cout<<" nota fisica: ";
cout<<P.fisica<<endl;
cout<<" nota quimica: ";
cout<<P.quimica<<endl;
cout<<" nota matematica: ";
cout<<P.matematica<<endl;
}
int main()
{
int C;
//float Po;
cout<<"Enter the number of people: ";
cin >> C;
persona * P1;
P1 = new persona [C];
for(int i = 0 ; i<C ; i++)
{
cout<<"Person "<<i+1<<" :"<<endl;
llenar(P1[i]);
// NOT USING void "llenar"
/*
cout<<"Igresa nombre: ";
cin>>P1[i].nombre;
cout<<"Igresa nota fisica: ";
cin>>P1[i].fisica;
cout<<"Igresa nota quimica: ";
cin>>P1[i].quimica;
cout<<"Igresa nota matematica: ";
cin>>P1[i].matematica;
*/
mostrar(P1[i]);
}
return 0;
}
To make a long story short, does someone knows how to fill a struct like "persona" from a void function?
You have to pass the argument by reference, so that it can be modified:
void llenar (persona P); // becomes ==>
void llenar (persona &P);

how can i put string after int in c++

i want to create a c++ program like that
Design and implement using C++, a class "Student" that stores the student id, name,
40
address and marks in five different subjects (in an array having five elements). Assume
that marks are out of 100. The class should have a constructor, a member function for
input of marks and an additional member functions which prints the student details
and marks, along with total marks and percentage. Write the main function which
creates two such student objects and displays their details
i want to insert student name and marks in this program but i am getting error why ...
this is my program..
please provide solution with example
#include <iostream>
#include<stdio.h>
using namespace std;
class student{
private:
int id;
char *name;
int marks[5];
char *address;
public:
student();
void input_detail();
void display_detail();
double total_marks();
double percentage();
};
student::student(){
id=0;
name='\0';
marks[5]=NULL;
address='\0';
}
void student::input_detail(){
int i=1,j=0;
cout<<"please enter student id: "<<endl;
cin>>id;
cout<<"please enter student name: "<<endl;
gets(name);
for(i=1,j=0;i<6;i++,j++){
cout<<"enter marks "<<i<<" subject : "<<endl;
cin>>marks[j];
}
cout<<"please enter student address : "<<endl;
gets(address);
}
double student::total_marks(){
double total_marks;
int i=0;
for(i=0;i<5;i++){
total_marks=total_marks+marks[i];
}
return total_marks;
}
double student::percentage(){
double percentage;
percentage=total_marks()/500*100;
return percentage;
}
void student::display_detail(){
int i=1,j=0;
cout<<"student id: "<<id<<endl;
cout<<"student id: "<<name<<endl;
for(i=1,j=0;i<6;i++,j++){
cout<<"marks "<<i<<" subject : "<<marks[j]<<endl;
}
cout<<"student address : "<<address<<endl;
cout<<"student total marks : "<<total_marks()<<endl;
cout<<"student percentage : "<<percentage()<<endl;
}
int main()
{
student s1;
s1.input_detail();
s1.display_detail();
return 0;
}
i am getting this output
please enter student id:
anil
please enter student name:
please enter student address :
annn
student id: 0
student id: anil
student address : annn
student total marks : 1.1331e-317
student percentage : 0
Process returned 0 (0x0) execution time : 19.901 s
Press any key to continue.
but where is the student marks it is not showing in program
A quick check shows me two errors:
The for condition is the opposite of what you think: when it's true the loop continues, when it's false the loop quits. A loop like for(int i=0; i>6; i++){...} will never run because the condition is false when starting (0 is not bigger than 6).
When you declare double a variable in C++ you need to initialize it; this error is present when computing the sum (start with double total_marks=0).
There are indeed many other errors and questionable approaches, but those are probably better discussed in class...

How to extract the details of the highest paid employee in files?

I am having problem in extracting the highest paid employee from empdetails.txt and finally displaying it to the user. i have completed getting the details from the user and merging the two files but for displaying highest paid using functions, i have no idea about it.
here is my code till now:
#include<iostream>
#include<conio.h>
#include<fstream>
using namespace std;
class emp
{
int num,age;
char name[20],dep[5];
public:
void getdata()
{
cout<<"\n\n Name = ";
cin>>name;
cout<<"\n Emp Num = ";
cin>>num;
cout<<"\n Department= ";
cin>>dep;
cout<<"\n Age = ";
cin>>age;
}
void display1()
{
cout<<"\n"<<name<<"\t"<<num<<"\t"<<dep<<"\t\t"<<age;
}
};
class sal
{
float gs,ns;
public:
void getsal()
{
cout<<"\n Gross sal = ";
cin>>gs;
cout<<"\n Net sal = ";
cin>>ns;
}
void display2()
{
cout<<"\t"<<gs<<"\t"<<ns;
}
};
void display()
{
emp e;sal s;
ifstream fil1;
fil1.open("empdetails.txt",ios::in);
cout<<"\n\n Name \t Emp Num \t Dep \t Age \t Gross Sal \t Net Sal \n";
while(!fil1.eof())
{
fil1.read((char*)&e,sizeof(e));
e.display1();
fil1.read((char*)&s,sizeof(s));
s.display2();
}
}
int main()
{
int n;
emp e1;sal s1;
ofstream fil1,fil2,fil3;
fil1.open("emp.txt",ios::out);
fil2.open("sal.txt",ios::out);
fil3.open("empdetails.txt",ios::out);
cout<<"\n How many employee details do you want to enter = ";
cin>>n;
cout<<"\n Enter the deatils one by one \n";
for(int i=0;i<n;i++)
{
e1.getdata();
fil1.write((char*)&e1,sizeof(e1));
s1.getsal();
fil2.write((char*)&s1,sizeof(s1));
fil3.write((char*)&e1,sizeof(e1));
fil3.write((char*)&s1,sizeof(s1));
}
fil1.close();
fil2.close();
fil3.close();
cout<<"\n\n\t\t Merged file contents \n\n\t\t";
display();
getch();
return 0;
}
how can i make a function and what conditions to use?
You don't need a function, there's already one: std::max_element. It can figure out that you're working on class emp (the first two arguments to std::max_element. It can't figure out that you want employees sorted by salary, so that is the third argument that you have to provide: a function that takes two employees and which returns true if the first employee earns less than the second. (Sounds weird, but this allows you to use the same function for std::min_element)

Reading into dynamically created pointer to array of structs

This is a class assignment that must be done using a dynamically created array of Course. I am trying to read into each member variable inside of course inside of my for loop but I'm not really sure how to do it. I did it with my student struct but the difference in this being an array is messing me up because I'm not sure how to proceed with it.
My problem is in the readCourseArray function when trying to read in struct members. If anyone could tell me how I do that I'd be appreciative. I know using the new operator isn't ideal along with many of the pointers being unnecessary but it is just how my instructor requires the assignment to be turned in.
#include <iostream>
#include <string>
using namespace std;
struct Student
{
string firstName, lastName, aNumber;
double GPA;
};
struct Course
{
int courseNumber, creditHours;
string courseName;
char grade;
};
Student* readStudent();
Course* readCourseArray(int);
int main()
{
int courses = 0;
Student *studentPTR = readStudent();
Course *coursePTR = readCourseArray(courses);
delete studentPTR;
delete coursePTR;
system ("pause");
return 0;
}
Student* readStudent()
{ Student* student = new Student;
cout<<"\nEnter students first name\n";
cin>>student->firstName;
cout<<"\nEnter students last name\n";
cin>>student->lastName;
cout<<"\nEnter students A-Number\n";
cin>>student->aNumber;
return student;
}
Course* readCourseArray(int courses)
{
cout<<"\nHow many courses is the student taking?\n";
cin>>courses;
const int *sizePTR = &courses;
Course *coursePTR = new Course[*sizePTR];
for(int count = 0; count < *sizePTR; count++) //Enter course information
{
cout<<"\nEnter student "<<count<<"'s course name\n";
cin>>coursePTR[count]->courseName>>endl;
cout<<"\nEnter student "<<count<<"'s course number\n";
cin>>coursePTR[count]->courseNumber;
cout<<"\nEnter student "<<count<<"'s credit hours\n";
cin>>coursePTR[count]->creditHours;
cout<<"\nEnter student "<<count<<"'s grade\n";
cin>>coursePTR[count]->grade>>endl;
}
return coursePTR;
}
Array subscript operator return an element of the array.
coursePTR[count] is equivalent to incrementing the pointer to the start of array and dereferencing the result, like: *(coursePTR + count). What you get is an object (or a reference to one) of type Course. So you'll need to use 'dot' operator, not 'arrow' operator to access the elements:
cin >> coursePTR[count].creditHours;
You've got another error:
cin >> coursePTR[count].courseName >> endl;
^^^^
This won't compile. endl can only be used on output streams.
Course* readCourseArray(int &courses); // Update the definition to pass "courses" by reference.
Course* readCourseArray(int &courses) // Pass the courses by reference so that your main() has the value updated.
{
cout<<"\nHow many courses is the student taking?\n";
cin>>courses;
/*
You don't need this line.
*/
// const int *sizePTR = &courses;
/*
You've allocated space for "courses" no. of "Course" objects.
Since this is essentially an array of "Course" object, you
just have to use the "." notation to access them.
*/
Course *coursePTR = new Course[courses];
/*
"endl" cannot be used for input stream.
*/
for(int count = 0; count < courses; count++) //Enter course information
{
cout<<"\nEnter student "<<count<<"'s course name\n";
cin>>coursePTR[count].courseName;
cout<<"\nEnter student "<<count<<"'s course number\n";
cin>>coursePTR[count].courseNumber;
cout<<"\nEnter student "<<count<<"'s credit hours\n";
cin>>coursePTR[count].creditHours;
cout<<"\nEnter student "<<count<<"'s grade\n";
cin>>coursePTR[count].grade;
}
return coursePTR;
}