Passing array of pointers to object c++ - c++

I have to create an array of pointer to class objects.
Then I have with function AddStudent I have to change/create a new student (add his data to pointer address).
In last step function ShowAllStudents has to show all students. But I shows only the last added student.
Every new object is beeing created in array index of 0. I don't know why.
There is my code:
index.html:
#include <iostream>
#include "student.h"
void AddStudent(Student* pointer_array[], int n)
{
int IndexNr{}, id{};
std::string name{}, surname{};
std::cout << "Write IndexNr:";
std::cin >> IndexNr;
for(int i = 0; i < n; i++){
if (IndexNr != pointer_array[i]->Student::IndexNr && pointer_array[i]->Student::name == "none")
{
i = id;
pointer_array[i]->Student::IndexNr = IndexNr;
break;
}
else if (IndexNr == pointer_array[i]->Student::IndexNr) {
i = id;
break;
}
}
std::cout << "Student's name: ";
std::cin >> name;
pointer_array[id]->Student::name = name;
std::cout << "Student's surname ";
std::cin >> surname;
pointer_array[id]->Student::surname = surname;
}
void ShowAllStudents(Student* pointer_array[], int n)
{
for (int i = 0; i < n; i++) {
if (pointer_array[i]->Student::name != "none")
{
std::cout << "<id>: " << pointer_array[i]->Student::IndexNr << " <Name>: " << pointer_array[i]->Student::name << " <Surname>: " << pointer_array[i]->Student::surname << std::endl;
}
else if (pointer_array[i]->Student::name != "none" && i == (n - 1))
std::cout << "<id>: no data" << std::endl;
}
}
int main()
{
int n{10};
Student* pointer_array[10];
for (int i = 0; i < n; i++)
pointer_array[i] = new Student;
AddStudent(pointer_array, n);
AddStudent(pointer_array, n);
AddStudent(pointer_array, n);
ShowAllStudents(pointer_array, n);
return 0;
}
student.h
#include <iostream>
#ifndef STUDENT_H_
#define STUDENT_H_
class Student {
public:
int IndexNr;
std::string name;
std::string surname;
Student() {
IndexNr = 0;
name = "none";
surname = "none";
}
};
#endif
It shows only the last edited student.

Related

How to initialize private variables in a different file and make it so it holds the value for other functions?

I just need to know how to have size, index, and counter keep their values when they are called in another function. Right now they are just being given random values when they are called instead of the values I'm initializing them with in the constructor. How can I fix this? The objective for this code is to make a program that Captures a string of words from a user of the program (via the keyboard) and adds the entered
words to a dynamic array of strings.
This is the array.cpp file
#include "array.h"
using namespace std;
Array::Array()
{
int size = 100;
int index = 0;
int counter = 0;
counter ++;
index++;
string *ptr = new string[size];
}
Array::~Array()
{
delete ptr;
ptr = nullptr;
}
void Array::populate()
{
string word;
cout << "Enter word to add to array: ";
cin >> word;
ptr[index] = word;
}
void Array::printContent()
{
cout << "Number of words in array: " << counter << endl;
cout << "Array size: " << size << endl;
cout << "Words in array: " << endl;
for (int i = 0; i < counter; i++)
{
cout << ptr[i] << endl;
}
}
void Array::displayMenu() const
{
cout << "[1] Add Word\n"
<< "[2] Print Array Information\n"
<< "[3] Quit Program\n"
<< "Enter Choice: ";
}
int Array::getChoice(int & choice1)
{
cin >> choice1;
while (choice1 < 1 || choice1 > 3) {
cout << endl;
cout << "Invalid Entry!!" << endl;
cout << "Enter Choice: ";
cin >> choice1;
}
return choice1;
}
int Array::endProgram(int & start2)
{
start2 = 0;
cout << "\n\n\t\tThank you for using this system!!\n\n";
return start2;
}
This is the array.h file
#include <iostream>
#include <string>
using namespace std;
class Array {
public:
Array();
~Array();
void populate();
void printContent();
void displayMenu() const;
int getChoice(int & choice1);
int endProgram(int & start2);
private:
int size;
int index;
int counter;
string *ptr;
};
Lastly this is the main.cpp file
#include <iostream>
#include "array.h"
using namespace std;
int main() {
int choice = 0;
int start = 1;
Array theArray;
while(choice != 3)
{
theArray.displayMenu();
theArray.getChoice(choice);
if(choice == 1)
{
theArray.populate();
}
if(choice == 2)
{
theArray.printContent();
}
if (choice == 3)
{
theArray.endProgram(start);
}
}
}
You are defining new local variables inside of your Array constructor and shadowing the member variables of the same name -- which is why the value isn't being preserved.
You only need to specify the type when defining new variables, but not when assigning to existing ones. To assign to the member variables, this should be:
Array::Array()
{
size = 100;
index = 0;
counter = 0;
ptr = new string[size];
...
}
Additionally, in constructors its more correct to use constructor initializer lists to initialize the values:
Array::Array()
: size{100},
index{0},
counter{0},
ptr{new string[size]}
{
...
}

Unable to get invalid emails

I'm unable to get invalid emails to print in my code. I'm able to call the student roster just fine but that's about it.
#include <iostream>
#include <string>
#include "student.h"
#include "degree.h"
#include "roster.h"
using namespace std;
int main()
{
const string studentData[] =
{
"A1,John,Smith,John1989#gm ail.com,20,30,35,40,SECURITY",
"A2,Suzan,Erickson,Erickson_1990#gmailcom,19,50,30,40,NETWORK",
"A3,Jack,Napoli,The_lawyer99yahoo.com,19,20,40,33,SOFTWARE",
"A4,Erin,Black,Erin.black#comcast.net,22,50,58,40,SECURITY",
};
Roster* classRoster = new Roster(numberOfStudents);
for (int i = 0; i < numberOfStudents; ++i)
{
cout << studentData[i] << "," << endl;
}
cout << endl;
cout << "Invalid emails:";
for (int i = 0; i < numberOfStudents; ++i)
{
classRoster->printInvalidEmails();
}
cout << "Average days per class for each student" << endl;
for (int i = 0; i < numberOfStudents; ++i)
{
cout << endl;
}
cout << endl;
classRoster->printByDegreeProgram();
cout << endl;
system("pause");
return 0;
}
Here is my roster.cpp
#include <iostream>
#include <string>
#include "student.h"
#include "degree.h"
#include "roster.h"
using namespace std;
Roster::Roster()
{
This->rosterSize = 0;
this->lastIndex = -1;
this->classRosterArray = nullptr;
}
Roster::Roster(int rosterSize)
{
this->rosterSize = rosterSize;
this->lastIndex = -1;
this->classRosterArray = new Student * [rosterSize];
}
void Roster::add(string studentId, string firstName, string lastName,
string
emailAddress, int age,
int daysInCourse1, int daysInCourse2, int daysInCourse3, Degree degree)
{
}
void Roster::remove(string studentId)
{
for (int i = 0; i <= lastIndex; ++i)
{
if (classRosterArray[i] == nullptr)
{
cout << "ERROR: Student with ID: " << studentId << " not found" <<
endl;
break;
}
else if (studentId == classRosterArray[i]->getStudentId())
{
classRosterArray[i] = nullptr;
cout << "Student removed" << endl;
}
}
}
void Roster::printAll()
{
for (int i = 0; i <= this->lastIndex; ++i)
{
(this->classRosterArray)[i]->print();
}
}
void Roster::printAverageDaysInCourse(string studentId)
{
bool found = false;
for (int i = 0; i <= lastIndex; ++i) {
if ((*classRosterArray[i]).getStudentId() == studentId) {
found = true;
int average = 0;
average = (classRosterArray[i]->getNumberOfDaysToCompleteCourse()
[0]
+ classRosterArray[i]->getNumberOfDaysToCompleteCourse()[1] +
classRosterArray[i]->getNumberOfDaysToCompleteCourse()[2]) /
3;
cout << "Average days it took student " << studentId << " to
complete
a course: " << average
<< " days" << endl;
}
}
if (!found) cout << "Student not found." << endl;
}
void Roster::printInvalidEmails()
{
for (int i = 0; i < numberOfStudents; ++i)
{
string email = classRosterArray[i]->getEmailAddress();
bool isBad = false;
size_t at = email.find("#");
size_t period = email.find(".");
if (at == string::npos)
{
cout << "Invalid email. Missing # symbol." << endl;
}
else if (period == string::npos)
{
cout << "Invalid email. Missing a period." << endl;
}
else if (email.find(" ") != string::npos)
{
cout << "Invalid email. Spaces not allowed." << endl;
}
}
}
void Roster::printByDegreeProgram()
{
for (int i = 0; i < degreeType; ++i)
{
cout << &Roster::printByDegreeProgram;
}
}
Roster::~Roster()
{
for (int i = 0; i < numberOfStudents; ++i)
{
delete classRosterArray[i];
}
}
I'm just starting out and am not sure if i've totally messed myself up. Any help would be greatly appreciated. I thought might have been able to figure it out and i've tried a few different times but still unable to correct.

Multiple errors with function header, and overloaded functions

it's my first time working with classes and headers in C++ and I ran into these errors after putting together my code
function does not take 1 arguments // For all 4 functions
overloaded member function not found in 'Animals' // Also for all 4 fncs
syntax error: identifier 'fstream' // header file error
The program is designed to read and write to a file, while also doing searches and being able to manipulate the binary file. I'm pretty sure the error is in my declarations somewhere but I can't figure it out myself; any help is appreciated.
main.cpp
#include <iostream>
#include<iomanip>
#include <fstream>
#include"animals.h"
using namespace std;
int main()
{
Animals nA;
fstream animalFile;
int choice;
cout << setprecision(2) << fixed;
do
{
// Display the menu.
cout << "\n1. Add a new animal\n";
cout << "2. Remove an animal\n";
cout << "3. Search and display a animal\n";
cout << "4. Display all animals\n";
cout << "5. Exit\n";
do
{
cout << "Enter your choice (1-5): ";
cin >> choice;
} while (choice < 1 || choice > 5);
// Process the selection.
switch (choice)
{
// Choice 1 is to add an animal
case 1:
nA.addAnimal(animalFile);
break;
// Choice 2 is to remove an animal
case 2:
nA.removeAnimal(animalFile);
break;
// Choice 3 is to search and display 1 animal
case 3:
nA.searchAnimal(animalFile);
break;
// Choice 4 is to display all animals
case 4:
nA.displayAnimal(animalFile);
}
} while (choice != 5);
system("pause");
return 0;
}
Animals.h
#ifndef ANIMALS_H
#define ANIMALS_H
#include <string>
#include <iostream>
#include <fstream>
class Animals
{
private :
std::string name;
int age;
public :
//Default constructor
Animals();
//Create an animal object
Animals(std::string name, int age);
//Add a new animal record
void addAnimal(fstream &d);
//Remove an animal record
void removeAnimal(fstream &d);
//Displays an animal through a search
void searchAnimal(fstream &d);
//Display ALL animals
void displayAnimal(fstream &d);
};
#endif
Animals.cpp
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include "Animals.h"
using namespace std;
Animals::Animals()
{
name = "NULL";
age = 0;
}
Animals::Animals(std::string name, int age)
{
Animals *newAnimal = new Animals;
}
void Animals::addAnimal(fstream &d)
{
string userName;
int userAge = 0;
int stringRemainder;
int record;
const int RECORD_SIZE = 40;
//Collecting user input
do
{
std::cout << "Please enter your animal name: ";
std::cin >> userName;
std::cout << "\n";
} while (sizeof(userName) > 30);
do
{
std::cout << "Please enter your animal age: ";
std::cin >> userAge;
std::cout << "\n";
} while (userAge <= 0 || !isdigit(userAge));
//Fixing length of string
stringRemainder = 30 - sizeof(userName);
//Finds record number based on position
record = (d.tellg() % RECORD_SIZE) + 1;
//Writing to file
d.close();
d.open("animals.txt", std::ios_base::app | ios::binary);
d << record << "";
d << userName;
for (int i = 0; i < stringRemainder; i++)
{
d << "";
}
d << userAge << "\n";
d.close();
}
void Animals::removeAnimal(fstream &d)
{
int recordNumber = 0;
const int RECORD_SIZE = 40;
char recordBuffer[RECORD_SIZE];
d.open("animals.txt", ios::out| ios::in |ios::binary);
//Collecting user input
do
{
cout << "Enter the record of the animal to be removed: ";
cin >> recordNumber;
} while (recordNumber <= 0 || !isdigit(recordNumber));
// move pointer to desired position, and overwrite!
d.seekp((recordNumber-1) * RECORD_SIZE);
d.write(recordBuffer, RECORD_SIZE);
d.close();
}
void Animals::searchAnimal(fstream &d)
{
int userRecord = 0;
char displayRecord[2];
const int RECORD_SIZE = 40;
char fileOutput[RECORD_SIZE];
string displayInfo;
char displayName[RECORD_SIZE];
char displayAge[2];
int i,k;
int j = 0;
d.open("animals.txt", ios::out | ios::binary);
//Getting user input
do
{
cout << "Enter the record of the animal to be diplayed: ";
cin >> userRecord;
} while (userRecord <= 0 || !isdigit(userRecord));
//Moving pointer position to searched value
d.seekp((userRecord - 1) * RECORD_SIZE);
//Gets data from file, stores into displayInfo
getline(d, displayInfo);
d.close();
//Entering file data into diplay variables,
//value 'i' increments through entire displayInfo array
for (i = 0; isdigit(displayInfo[i]); i++)
{
displayRecord[i] = displayInfo[i];
}
//New sentinel for ONLY string cap including buffer
k = i + 30;
for (i; i < k; i++)
{
displayName[j] = displayInfo[i];
j++;
}
//Finishes off last of the displayInfo array
for (i; i < sizeof(displayInfo); i++) {
displayAge[i] = displayInfo[i];
}
//Prints the data for user
cout << "For record number: " << userRecord << "\n";
cout << "Animal: ";
for (int i = 0; i < strlen(displayName); i++)
{
cout << displayName[i];
}
cout << "\n";
cout << "Age: ";
for (int i = 0; i < strlen(displayAge); i++)
{
cout << displayAge[i];
}
cout << "\n";
}
//Mostly copied from above function, displays ALL animals
void Animals::displayAnimal(fstream &d)
{
int userRecord = 0;
char displayRecord[2];
const int RECORD_SIZE = 40;
char fileOutput[RECORD_SIZE];
string displayInfo;
char displayName[RECORD_SIZE];
char displayAge[2];
int numberOfRecords;
int i, k;
int j = 0;
int q = 0;
d.open("animals.txt", ios::out | ios::in | ios::binary);
d.seekg(0, d.end);
numberOfRecords = d.tellg() % RECORD_SIZE;
d.seekg(0, d.beg);
for (int q; q < numberOfRecords; q++) {
d.seekp(q * RECORD_SIZE);
//Gets data from file, stores into displayInfo
getline(d, displayInfo);
//Entering file data into diplay variables,
//value 'i' increments through entire displayInfo array
for (i = 0; isdigit(displayInfo[i]); i++)
{
displayRecord[i] = displayInfo[i];
}
//New sentinel for ONLY string cap including buffer
k = i + 30;
for (i; i < k; i++)
{
displayName[j] = displayInfo[i];
j++;
}
//Finishes off last of the displayInfo array
for (i; i < sizeof(displayInfo); i++) {
displayAge[i] = displayInfo[i];
}
//Prints the data for user
cout << "For record number: " << userRecord << "\n";
cout << "Animal: ";
for (int i = 0; i < strlen(displayName); i++)
{
cout << displayName[i];
}
cout << "\n";
cout << "Age: ";
for (int i = 0; i < strlen(displayAge); i++)
{
cout << displayAge[i];
}
cout << "\n\n";
}
d.close();
}
The headers <iostream> and <fstream> bring their symbols into the std namespace, so any reference to these symbols in the header need to be fully qualified; e.g. std::fstream. Also, you might want to include <iosfwd> in your headers instead - this minimizes the compiler time cost of importing the header, assuming that the header only uses reference to the symbols mentioned in the iostream header.
You should use ifstream for read files and ofstream for write files.
And in header file, you should use std::ifstream & d or std::ofstream & d in argument of 4 functions.

C++ Console is blank when program is run

This might be a stupid question I'm still very new to coding. For my CS class I was given code for the basics of a boardgame. When I try to run the code it just comes up blank in my console, I tried to print "check" at the very beginning of main but still nothing prints to the console. No errors come up
#include <iostream>
#include <string>
#include <fstream>
#include <ctime>
#include <cstdlib>
using namespace std;
class square {
private:
int move;
string message;
char symbol;
public:
square();
void print();
int action();
void set(int, char, string);
};
void print_board(square[], int, int);
void read_board(square[]);
void check_position(int &);
const int board_length = 20;
int main() {
cout << "check";
int current_player = 1, roll;
int player1_position = 0, player2_position = 0;
square the_board[board_length];
srand(time(NULL));
read_board(the_board);
print_board(the_board, player1_position, 1);
print_board(the_board, player2_position, 2);
do {
cout << "\n\n\nPlayer " << current_player << " type enter to roll.\n";
cin.ignore();
roll = 1 + (rand() % 5);
cout << "Player " << current_player << " rolled a " << roll << ".\n";
if (current_player == 1) {
player1_position += roll;
check_position(player1_position);
player1_position += the_board[player1_position].action();
check_position(player1_position);
} else {
player2_position += roll;
check_position(player2_position);
player2_position += the_board[player2_position].action();
check_position(player2_position);
}
print_board(the_board, player1_position, 1);
print_board(the_board, player2_position, 2);
current_player = (current_player % 2) + 1;
} while ((player1_position < board_length-1) && (player2_position < board_length - 1));
current_player = (current_player % 2) + 1;
cout << "\nPlayer " << current_player << " Wins!!!\n";
cin.ignore();
return 0;
}
void read_board(square b[]) {
ifstream infile;
infile.open("game.txt");
int square_number, square_move;
string square_message;
char square_symbol;
while (!infile.eof()) {
infile >> square_number >> square_move >> square_symbol;
getline(infile, square_message);
if (square_number < board_length) {
b[square_number].set(square_move, square_symbol, square_message);
}
}
}
void print_board(square b[], int player_position, int player_number) {
for (int i=0; i < board_length; i++) {
if (i != player_position) {
b[i].print();
} else {
cout << player_number;
}
}
cout << "Goal\n";
for (int i=0; i < board_length; i++) {
cout << "-";
}
cout << "\n";
}
void check_position(int &p) {
if (p < 0) {
p = 0;
}
if (p >= board_length) {
p = board_length - 1;
}
}
square::square() {
symbol = ' ';
move = 0;
message = "";
}
int square::action() {
cout << message << endl;
return move;
}
void square::print() {
cout << symbol;
}
void square::set (int m, char s, string a_message) {
move = m;
symbol = s;
message = a_message;
}
Modify you read_board() to
void read_board(square b[]) {
ifstream infile;
infile.open("game.txt");
int square_number, square_move;
string square_message;
char square_symbol;
while (infile >> square_number >> square_move >> square_symbol) {
getline(infile, square_message);
if (square_number < board_length) {
b[square_number].set(square_move, square_symbol, quare_message);
}
}
}
Change cout<<"check"; to cout<<"check"<<endl;
Without the new line added, the out buffer is not flushed before your code gets hung in your read_board function

C++ Sort class array using qsort

C++:
I'm trying to sort some students that are stored in a class by average media.
Only qsort, don't advice me of std::sort, thank you!
Qsort compare function:
int cmp(Student *a, Student *b) {
return (int)(((Student *)b)->get_media() - ((Student *)a)->get_media());
}
qsort call:
qsort(&tab, (size_t)n, sizeof(tab), (int(*)(const void*, const void*))cmp);
There's no compiler error, but it won't sort.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Student {
private:
char name[20];
char surname[20];
int *marks;
int group;
float avg_mark;
public:
Student()
{
char na[20], sur[20];
int group;
cout << "\nEnter name: ";
cin >> na;
cout << "\nEnter surname: ";
cin >> sur;
cout << "\nEnter group: ";
cin >> group;
init(na, sur, group);
}
~Student()
{
cout << "\ndestructor";
delete []marks;
}
void init(char *n, char *p, int gr)
{
strcpy(name, n);
strcpy(surname, p);
group = gr;
marks = new int[6];
for (int i = 0; i < 6; i++)
{
cout << "\nEnter mark " << i + 1 << ": ";
cin >> *(marks + i);
}
avg_mark = media();
}
float media()
{
int s = 0;
for (int i = 0; i < 6; i++)
s += marks[i];
return ((float)s / 6);
}
void set_name(char *n)
{
strcpy(name, n);
}
char* get_name()
{
return name;
}
void set_surname(char *p)
{
strcpy(name, p);
}
char* get_surname()
{
return surname;
}
int get_group()
{
return group;
}
float get_media()
{
return avg_mark;
}
};
int cmp(Student *a, Student *b);
int comparator(void *a, void *b) {
return (int)(((Student *)b)->get_media() - ((Student *)a)->get_media());
}
void main(void)
{
int n;
cout << "\nEnter n: ";
cin >> n;
Student *tab = new Student[n];
for (int i = 0; i < n; i++)
cout << i + 1 << ". " << tab[i].get_name() << " " << tab[i].get_surname() << " Group:" << tab[i].get_group() << " Average mark: " << tab[i].get_media() << endl;
//qsort(&tab[0], (size_t)n, sizeof(tab), (int*)cmp);
cout << endl;
qsort(&tab, (size_t)n, sizeof(tab), (int(*)(const void*, const void*))cmp);
for (int i = 0; i < n; i++)
cout << i + 1 << ". " << tab[i].get_name() << " " << tab[i].get_surname() << " Group:" << tab[i].get_group() << " Average mark: " << tab[i].get_media() << endl;
cin.ignore();
cin.get();
}
int cmp(Student *a, Student *b) {
return (int)(((Student *)b)->get_media() - ((Student *)a)->get_media());
}
qsort(&tab, (size_t)n, sizeof(tab), (int(*)(const void*, const void*))cmp);
&tab is the address of the pointer tab. You want to pass the address of the first element of your array. That's &tab[0] or simply tab.
Also, you need to pass the size of a Student object, not the size of a pointer. So change sizeof(tab) to sizeof(Student) or sizeof(*tab). So the call should look like this:
qsort(tab, (size_t)n, sizeof(*tab), (int(*)(const void*, const void*))cmp);