C++: Student Record Program - c++

I am in desperate need of help. I am supposed to create a student record using structs and vectors.
In the program, I should have:
For a given student, identified either by name or student number
(a) Enter a new student into the record. (Assume no courses completed.)
(b) Grade point average
(c) Transcript, i.e. a list of courses taken, including credit value and grade earned
(d) Record a newly completed course
A listing, sorted by name, of all students who have taken a given course.
A listing, sorted by grade point average, of all students and their grade point averages,
who are on probation, i.e. have a grade point average < 2.0 .
This is what I have so far... and I seem to be having troubles with the user input how read it into my structs
using namespace std;
struct courses {
string courseName;
int courseNum;
double credit;
char grade;
};
struct students {
string name;
int id;
vector<courses> c;
};
int main() {
// variables
string name;
char selector;
students s;
courses d;
vector<students> student;
vector<courses> course;
// (1) create a menu: (a) user input, (b) echo record (with overall gpa), (c) failed students
do {
// prompt for user input
cout << "Enter Q to (Q)uit, (C)reate new student record, (S)how all record(s) on file, show students on (P)robation: ";
cin >> selector;
selector = toupper(selector);
switch (selector) {
// (a) ask and get for user input:
// student info first
// courses second
case 'C':
// variables within case C
char answer;
char answerAddAnotherCourseEntry;
char answerToAnotherStudentRecord;
do {
cout << "Enter your name and student ID number: ";
cin >> s.name >> s.id;
student.push_back(s);
do {
cout << "Do you want to create a student course entry ('y' or 'n')? ";
cin >> answer;
answer = toupper(answer);
cout << "Enter your course number, course name, grade received and credit worth: ";
cin >> d.courseNum >> d.courseName >> d.grade >> d.credit;
course.push_back(d);
cout << "Add another student course entry ('y' or 'n'): ";
cin >> answerAddAnotherCourseEntry;
answerAddAnotherCourseEntry = toupper(answerAddAnotherCourseEntry);
} while (answer == 'N');
cout << "Add another student record ('y' or 'n'): " << endl;
cin >> answerToAnotherStudentRecord;
answerAddAnotherCourseEntry = toupper(answerToAnotherStudentRecord);
} while (answerToAnotherStudentRecord == 'N');
break;
// (b) echo record of vectors
// sort by name
case 'S':
if (student.empty()) {
cout << "\nSorry, no records exist in the database.";
}
else
for (int count = 0; count < student.size(); count++) { //For Loop to Display All Records
cout << "Student name: " << student[count].name << "ID Number: " << student[count].id << endl;
count++;
// another for loop i think
for (int i = 0; i < course.size(); i++) {
cout << "Course info: " << " " << course[i].courseNum << " " << course[i].courseName << " " << course[i].credit << " " << course[i].grade << endl;
i++;
}
}
cout << endl;
break;
// (c) separate failed student into another vector
// sort by gpa
case 'P':
break;
} // bracket closing switch
} // bracket closing do while
while (selector != 'q' && selector != 'Q'); // first do while

The issues I see with your input is that you are trying to store the user input directly in a string, here e.g. in the variable name of the struct s:
cout << "Enter your name and student ID number: ";
cin >> s.name >> s.id;
This does not compile. Instead you can store the name in a temporary char array first and then copy it to s.name.
char studentName[128];
cout << "Enter your name and student ID number: ";
cin >> studentName >> s.id;
s.name = studentName;
You can also work with getline() if you want to store your input directly in a string.
Furthermore you try to directly output the variable student[count].name, which is a string, to cout:
cout << "Student name: " << student[count].name << "ID Number: " << student[count].id << endl;
Converting the string to a char array first makes this compile:
cout << "Student name: " << student[count].name.c_str() << "ID Number: " << student[count].id << endl;

Related

My program is not correctly outputting the amount of students in my struct

i am making a program which is supposed to collect input from the user by asking for id, name, units attempted, units earned and the gpa of a student and store that into a struct. Currently, when i input more than one student into the struct, it only outputs the last student in the array. What can i do to fix this?
Here is my code
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
struct Student {
string ID; //an 8-digit student ID
string name; //name of the student
unsigned unitsAttempted;//number of units attempted by the student
unsigned unitsEarned; //number of units earned by the student
double gpa; //the grade point average for the student
};
int main()
{
Student students[10];//array for 10 Student Structs
char answer = 'y';
int number = 0;
while ((answer == 'y') || (answer == 'Y')) {
//prompt the user to enter the data
{
answer = ' ';
int i = 0;
cout << "Enter the students ID: \n" ;
getline(cin, students[i].ID);
cout << "\nEnter the name:\n";
getline(cin, students[i].name);
cout << "\nEnter the units attempted:\n";
cin >> students[i].unitsAttempted;
cin.ignore();
cout << "\nEnter the units earned:\n";
cin >> students[i].unitsEarned;
cin.ignore();
cout << "\nEnter the GPA: \n";
cin >> students[i].gpa;
cin.ignore();
cout << "\nWould you like to add another student? y or n\n";
cin >> answer;
cin.ignore();
i++;
number++;
}
}
cout << left << setw(10) << "ID " << setw(20) <<"Name" << setw(20) <<"Units Attempted" << setw(20) <<"Units Earned" << setw(10) <<"GPA";
cout << "\n===============================================================\n";
for (int i = 0; i < number; i++)//display the students
{
cout << left << setw(10) << students[i].ID << setw(20) << students[i].name << setw(20) <<students[i].unitsAttempted << setw(20) <<students[i].unitsEarned << setw(10) <<students[i].gpa << endl << endl;
}
return 0;
}
Im still learning so please go easy on me, thanks.
Currently, when i input more than one student into the struct, it only outputs the last student in the array.
It looks most likely that the scope of your i is incorrect:
int i = 0; //<-- this should be declared outside the `while` loop
As it stands, your i is scoped inside while loop, so it will be reset every time the while loop is entered. In other word, that i never increased.

fix repeating "enter names of teacher" after I finish the input?

this code should record school data names and address but after input it repeats "enter names of teachers:" line several times before the output of data entered successfully how can i fix this problem? any tweaks in the code to achieve this? it should be school projects in C++ but I can't fix this problem at all I would apprecciate any help
#include <iostream>
#include <stack>
using namespace std;
int main()
{
string sname, saddress, sname_teacher;
int snumber_classrooms;
double ratio, snumber_students, snumber_teachers;
//Entering data of school
cout << "Enter school data: \n";
cout << "Enter name of school : ";
cin >> sname;
cout << "Enter an address of school : ";
cin >> saddress;
cout << "Enter number of classrooms of the school : ";
cin >> snumber_classrooms;
cout << "Enter number of students of the school : ";
cin >> snumber_students;
cout << "Enter number of teachers of the school : ";
cin >> snumber_teachers;
//check if number of teachers < 20 or not
if (snumber_teachers > 20) {
while (snumber_teachers > 20) {
cout << " The number of teachers should not be more than 20 teachers. \n";
cout << "Enter number of teachers of the school : ";
cin >> snumber_teachers;
}
}
//check if number of teachers : number of students < (1/50=0.02)
ratio = snumber_teachers / snumber_students;
while (ratio < 0.02) {
cout << " The number of teachers should not be less than 1/50 number of students. \n";
cout << "Enter number of teachers of the school : ";
cin >> snumber_teachers;
ratio = snumber_teachers / snumber_students;
}
// Entering names of teachers
int snumber_teachers2 = snumber_teachers;
stack<string> names;
for (int i = 0; i < snumber_teachers2; i++) {
cout << "Enter names of teachers : ";
cin >> sname_teacher;
names.push(sname_teacher);
}
cout << " \n The Data of shool has entered succedly :)\n \n";
// Printing data of school
cout << " _______________________The Data of school are_______________________ \n";
cout << " name : " + sname << endl;
cout << " address " + saddress << endl;
cout << " classrooms : " << snumber_classrooms << endl;
cout << " students : " << snumber_students << endl;
cout << " teachers : " << snumber_teachers << endl;
cout << " names of teachers : \n";
// Printing content of stack
while (!names.empty()) {
cout << ' ' << names.top();
names.pop();
cout << "\n";
}
return 0;
}
You want to receive several inputs for teacher names, but only prompt "Enter names of teachers : " once.
So change
for (int i = 0; i < snumber_teachers2; i++) {
cout << "Enter names of teachers : ";
cin >> sname_teacher;
names.push(sname_teacher);
}
to
cout << "Enter names of teachers : ";
for (int i = 0; i < snumber_teachers2; i++) {
cin >> sname_teacher;
names.push(sname_teacher);
}
I.e. keep what you want to repeat inside the loop,
but move what you only want once outside.

How to display user account only using user ID num

Im basically making a database that stores a users account info. (Name, Phone number, ID, etc) I want to be able to display a specific persons info by entering in their ID num.
I have a struct with basic info and an array struct that stores each person and their info. I need to be able to type in a persons ID and have it display their info.
(I am still in first year of CS degree plz be gentle lol)
struct Account{
string name;
string city;
string state;
int ZIP;
int phone;
int IDNUM;
double ACT_BAL;
string LST_PMNT;};
Main fuction
const int SIZE = 20;
Account customers[SIZE];
const int NEW_INFO = 1, CHNG_INFO = 2, DISP = 3, EXIT = 4;
char choice1;
int choice;
int n;
int NEWCUST;
int results;
do
{ // menu display
cout << "Customer Database\n"
<< "----------------------------\n"
<< "1. Enter new account info\n"
<< "2. Change account info\n"
<< "3. Display all account info\n"
<< "4. Exit\n";
cin >> choice;
//respond to user input
switch (choice)
case NEW_INFO:
cout << "Would you like to enter a new cusomter?\n"
<< "(Y/N)";
cin >> choice1;
if (choice1 == 'Y' || choice1 == 'y')
{
cout << "How many new customers?" << endl; //User eneters in new customer info without having to enter in a full array worth of customers.
cin >> NEWCUST;
for (n = 0; n < NEWCUST; n++)
{
cout << "ID Number: ";
cin >> customers[n].IDNUM;
cout << "Enter in a name: ";
cin >> customers[n].name;
cout << "City: ";
cin >> customers[n].city;
cout << "State: ";
cin >> customers[n].state;
cout << "ZIP code: ";
cin >> customers[n].ZIP;
cout << "Phone number: ";
cin >> customers[n].phone;
cout << "Account Balance: ";
cin >> customers[n].ACT_BAL;
cout << "Lasy payment date: ";
cin >> customers[n].LST_PMNT;
}
}
break;
case CHNG_INFO: // Changes info
break; // displays all info (work in progress)
case DISP:
cout << "Enter customers ID number" << endl;
cin >> customers[].IDNUM;
results = linearSearch(customers, SIZE, customers[].IDNUM);
break;
case EXIT:
cout << "Cosing......" << endl; //exits progeam
break;
To get a specific user details, you can do the following:
Declaring num as short int to hold a simple User ID, you can change it. N = 50 as you've provided the constant. Now, unless the loop finds the inputted ID matching with one of the struct's idNum, it'll be executed 50 times (max).
cout << "Input account code: ";
cin >> num;
for (int i = 0; i < N; i++)
{
if (num == acc[i].idNum)
{
cout << "Name: " << acc[i].name << endl
<< "..." << endl;
}
}

Checking integer for input validation of a node

I'm trying to do my input validation where I have already predefined data in my program. When I want the user to key in a new employee id, I want it to check whether that ID is already in the database, if yes, how do i keep looping it until the user types in an id which is not in the database?
struct employee {
int empNo, salary, performance;
string name, phoneNo, address, depNo, depName;
employee* next;
employee* previous;
} *temp, *head, *tail, *newhead, *newtail, *newnode;
void validate()
{
cout << "Input not accepted, please try again!" << endl;
cin.clear();
cin.ignore(INT_MAX, '\n');
}
int main()
{
int choice = 1;
int num, salary, performance = 0;
string name, hpnum, depName, depNo, address;
bool execute = true;
insertemployeerecord(0002, "Ethan Tan", 16000, "017-2399193", "Kuala Lumpur, Malaysia", "F001", "Finance", 2);
insertemployeerecord(0003, "Nikshaen Kumar", 15000, "016-9188131", "Los Angeles, California", "A001", "Audit", 3);
insertemployeerecord(0001, "Koughen Mogan", 17500, "014-1233241", "Los Angeles, California", "F001", "Finance", 4);
while (execute)
{
cout << "..........................................................." << endl;
cout << " EMERGE EMPLOYEE SYSTEM " << endl;
cout << "..........................................................." << endl;
cout << endl;
cout << "1. Add an Employee Record" << endl;
cout << "2. Display All Records" << endl;
cout << "3. Search by Employee ID" << endl;
cout << "4. Search by Employee overall performance" << endl;
cout << "5. Sort and display by Employee ID in ascending order" << endl;
cout << "6. Sort and display by Employee Salary in ascending order " << endl;
cout << "7. Sort and display by Employee Overall Performance in ascending order " << endl;
cout << "8. Modify an Employee Record" << endl;
cout << "9. Delete an Employee Record" << endl;
cout << "10. Calculate salary package of an employee" << endl;
cout << "11. Exit" << endl;
cout << endl << endl;
cout << "Select your option: ";
cin >> choice;
if (choice == 1)
{
system("cls");
cout << "Enter employee number: ";
cin >> num;
while (!cin >> num) //to see if user types anything besides number
{
validate();
cout << "Enter employee number: ";
cin >> num;
}
temp = head;
bool verify = true;
if (temp != NULL)
{
while (temp->empNo != num)
{
temp = temp->next;
if (temp == NULL)
{
verify = false;
break;
}
}
while (verify == true) //if the user types an id that is found in the database
{
validate();
cout << "Employee found in database!" << endl;
cout << "Enter employee number: " << endl;
cin >> num;
}
if (verify == false)
{
cin.get();
}
}
cout << endl;
cout << "Enter employee name: ";
getline(cin, name);
As you can see, my output can detect if there is an alphabet being typed and also if the user types an id thats already in the database, but when I type a new id, example being 4, the system still says it detects from the database
Enter employee number: a
Input not accepted, please try again!
Enter employee number: 1
Input not accepted, please try again!
Employee found in database!
Enter employee number:
2
Input not accepted, please try again!
Employee found in database!
Enter employee number:
3
Input not accepted, please try again!
Employee found in database!
Enter employee number:
4
Input not accepted, please try again!
Employee found in database!
You can do something like this :
int enter_employee_number() {
int number;
do{
cout << "Enter employee number: ";
cin >> number;
bool fail = cin.fail();
if(fail)
cout << "Input not accepted, please try again!" << endl;
} while (fail);
return number;
}
string enter_employee_name() {
string name;
do{
cout << "Enter employee name: ";
cin >> name;
bool fail = cin.fail();
if(fail)
cout << "Input not accepted, please try again!" << endl;
} while (fail);
return name;
}
employee get_employee(int number) {
// retrieve your employee and return it.
}
int main() {
// other part of your code
if (choice == 1) {
system("cls");
while(true) {
int empNo = enter_employee_number();
employee emp = get_employee();
if (emp != nullptr) {
cout << "Employee found in database!" << endl;
string empName = enter_employee_name();
// call method that use empName
}
else {
cout << "Employee not found in database!" << endl;
}
cout << endl;
}
}
}
Recommended way of input validation is via getting everything in a string, like define string inputLine and use std::getline() and then parsing it using std::istringstream(inputLine). If you want to continue till validation succeeds, put below code in loop.
if ( stringStream >> ID >> std::ws && stringStream.get() == EOF)
//At this point you have Employee Id in ID variable , Now you can do database check.
if(validate(ID)) // if validation succeeds.
break; // Break out of loop, otherwise continue till you get correct input.

Using a struct to hold information entered by the user C++

Okay, so I am writing a C++ program to declare a struct data type that holds the following information on an employee (First Name, Last Name, ID, Pay Rate, and Hours). My problem is that the user can only enter in the ID and First Name, then the whole program runs without letting the user enter the rest of the data.
Heres my code:
#include <iostream>
#include <iomanip>
using namespace std;
struct Employee
{
int employeeID;
char firstName;
char lastName;
float payRate;
int hours;
};
int main()
{
int i, j;
cout << "How Many Employees Do You Wish To Enter?:\n\n";
cin >> j;
Employee info;
for (i = 0; i < j; i++)
{
cout << "Enter in the Data for Employee number " << i + 1 << endl;
cout << setw(5) << "\n Please Enter The Employee ID Number: ";
cin >> info.employeeID;
cout << setw(5) << "\n Please Enter Employees First Name: ";
cin >> info.firstName;
cout << setw(5) << "\n Please Enter Employees Last Name: ";
cin >> info.lastName;
cout << setw(5) << "\n Please Enter Employees Pay Rate: ";
cin >> info.payRate;
cout << setw(5) << "\n Please Enter The Hours The Employee Worked:
";
cin >> info.hours;
}
cout << "\n\n \n";
cout << "ID" << setw(15) << "First Name" << setw(10) << "Last Name" <<
setw(10) << "Pay Rate" << setw(10) << "Hours";
cout << endl;
for (i = 0; i < j; i++)
{
cout << "\n" << info.employeeID << setw(15) << info.firstName << setw(10) << info.lastName << setw(10) << info.payRate << setw(10) << info.hours;
}
cout << "\n\n \n";
system("pause");
return 0;
};
#include <iostream>
#include <iomanip>
#include <string> //Allows you to use strings, which are way more handy for text manipulation
#include <vector> //Allows you to use vector which are meant to be rezied dynamicaly, which is your case
using namespace std;
struct Employee
{
int employeeID;
string firstName; //HERE : use string instead of char (string are array of char)
string lastName; //HERE : use string instead of char
float payRate;
int hours;
};
int main()
{
int j;
cout << "How Many Employees Do You Wish To Enter?:\n\n";
cin >> j;
vector<struct Employee> info; //creation of the vector (dynamic array) to store the employee info the user is going to give you
for (int i = 0; i < j; i++) //declare your looping iterator "i" here, you will avoid many error
{
struct Employee employee_i; // create an employee at each iteration to associate the current info
cout << "Enter in the Data for Employee number " << i + 1 << endl;
cout << "\n Please Enter The Employee ID Number: ";
cin >> employee_i.employeeID;
cout << "\n Please Enter Employees First Name: ";
cin >> employee_i.firstName;
cout << "\n Please Enter Employees Last Name: ";
cin >> employee_i.lastName;
cout << "\n Please Enter Employees Pay Rate: ";
cin >> employee_i.payRate;
cout << "\n Please Enter The Hours The Employee Worked: ";
cin >> employee_i.hours;
info.push_back(employee_i); //store that employee info into your vector. Push_back() methods expands the vector size by 1 each time, to be able to put your item in it
} // because you employee variable was create IN the loop, he will be destruct here, but not the vector which was created outside
cout << "\n\n \n";
for (int i = 0; i < j; i++) //the loop to get back all the info from the vector
{
cout << "ID :" << info[i].employeeID << " First Name :" << info[i].firstName << " Last Name :" <<
info[i].lastName << " Pay Rate :" << info[i].payRate << " Hours :"<< info[i].hours;
cout << endl;
//notice the info[i], which leads you to the employee you need and the ".hours" which leads to the hours info of that specific employee
}
system("pause");
return 0;
}
First, please read Tips and tricks for using C++ I/O (input/output). It might be helpful to understand C++ I/O.
Here are some comments on your code:
First
Use string instead of char.
struct Employee
{
int employeeID;
string firstName;
string lastName;
float payRate;
int hours;
};
Second
Use array of Employee object to store multiple employees.
Employee info[100];
Third
Use cin carefully depending data types. In your case, it would be something like this:
cout << "Enter in the Data for Employee number " << i + 1 << endl;
cout << setw(5) << "\n Please Enter The Employee ID Number: ";
cin >> info[i].employeeID;
cin.ignore(); //It is placed to ignore new line character.
cout << setw(5) << "\n Please Enter Employees First Name: ";
getline (cin, info[i].firstName);
cout << setw(5) << "\n Please Enter Employees Last Name: ";
getline (cin, info[i].lastName);
cout << setw(5) << "\n Please Enter Employees Pay Rate: ";
cin >> info[i].payRate;
cout << setw(5) << "\n Please Enter The Hours The Employee Worked: ";
cin >> info[i].hours;
Fourth
std::getline() can run into problems when used before std::cin >> var. So, std::cin.ignore() can be used in this case to solve the problem.
I hope it helps.