How to pass struct array arguments to a function the right way?

Viewed 90

Source Code:

#include <iostream>

using namespace std;

struct Employee {

   string name;
   int age;
   float salary;

};

void displayData(Employee);

int main() {

   Employee employee[3];
   int sizeOfEmployee = sizeof(employee) / sizeof(employee[0]);

   for(int i = 0; i < sizeOfEmployee; i++) {
       cout << "Enter name for employee " << i + 1 << ": ";
       cin >> employee->name;
       cout << "Enter age for employee " << i + 1 << ": ";
       cin >> employee->age;
       cout << "Enter salary for employee " << i + 1 << ": ";
       cin >> employee->salary;       
}

   for(int i = 0; i < sizeOfEmployee; i++) {
       displayData(employee[i]);
}

}

void displayData(Employee employee) {

   cout << "DISPLAYING INFORMATION" << endl;
   cout << "Name: " << employee.name << endl;
   cout << "Age: " << employee.age << endl;
   cout << "Salary: " << employee.salary << endl;

}

My code doesn't display all the data i've stored into the array, it only reads and display the last data i've inputted.

CODE OUTPUT:

CODE OUTPUT:

In what way could i possibly get all the data i've stored into the array and display it?

5 Answers

You are reading data into a pointer to the first element of the array. To read into n-th element your code should be using indexing, like cin >> employee[i].name;.

However...

"Naked" arrays are a source of many errors, subtle bugs, and generally unsafe code. Consider using std::array instead - this will eliminate the need for code like int sizeOfEmployee = sizeof(... and will nicely encapsulate that array as a parameter to a function:

#include <array>

int main() {

   std::array<Employee, 3> employee;

   for(int i = 0; i < employee.size(); i++) {
       cout << "Enter name for employee " << i + 1 << ": ";
       cin >> employee[i].name;
   // the rest of that for loop...
   }
// and the second loop becomes:
   for(const auto& e: employee) {
       displayData(e);
}

You are reading data 3 times into the first element in your array:

Employee employee[3];

for(int i = 0; i < sizeOfEmployee; i++) {
    cout << "Enter name for employee " << i + 1 << ": ";
    cin >> employee->name; // employee points to the first element in the array
}

One more comment: your are passing the Employee class by value just to display it. It would be mych better, efficient and robust to pass it by const reference:

void displayData(const Employee&);
int sizeOfEmployee = sizeof(employee) / sizeof(employee[0]); 

Don't do this. Use std::size(employee) if you want to get the length of the array.

for(int i = 0; i < sizeOfEmployee; i++) {

Don't do this. Instead, use a range-for to loop over all elements of a range:

for (auto&& e : employee)

Which incidentally will fix the bug that you had. The bug is that you always write to the first element of the array. Each iteration over-writes the previous ones and the other elements remain uninitialised.

The range-for will correctly iterate all elements with less chance of messing things up.

If you want to input a variable number of employees, then you should use the STL container std::vector. Please have a look at its documentation.

Below you find the usage of std::vector for your given code as well as some hints starting with the label //CKE:.

#include <iostream>
#include <vector> //CKE: Very powerful STL container for arrays

using namespace std;

struct Employee {
   string name;
   int age = INT_MIN; //CKE: Always initialize variables in C++
   float salary = 0.; //CKE: Always initialize variables in C++
};

void displayData(const Employee&); //CKE: Use const reference if possible

int main() {

   vector<Employee> employees; //CKE: Declaration of dynamic array in C++
   size_t counter = 0;         //CKE: Counts number of given data sets
   string addOneMore;          //CKE: Holds check for more input data
   do {
       ++counter;
       Employee employee;
      cout << "Enter name for employee " << counter << ": ";
      cin >> employee.name;
      cout << "Enter age for employee " << counter << ": ";
      cin >> employee.age;
      cout << "Enter salary for employee " << counter << ": ";
      cin >> employee.salary;
      employees.push_back(employee); //CKE: Save data in dynamic array
      cout << "Want to add another employee? (y/n): ";
      cin >> addOneMore;
   } while (addOneMore == "y");

   for (const auto& employee : employees) { //CKE: Use range base loop for output
      displayData(employee);
   }
   return 0; //CKE: Always return an integer in int main function of C++
}

void displayData(const Employee& employee) { //CKE: No copying of struct Employee
   cout << "DISPLAYING INFORMATION" << endl;
   cout << "Name: " << employee.name << endl;
   cout << "Age: " << employee.age << endl;
   cout << "Salary: " << employee.salary << endl;
}

I simply fixed my problem by using loop counter:

#include <iostream>

using namespace std;

struct Employee {

   string name;
   int age;
   float salary;

};

void displayData(Employee[], int);

int main() {

   Employee employee[3];
   int sizeOfEmployee = sizeof(employee) / sizeof(employee[0]);

   for(int i = 0; i < sizeOfEmployee; i++) {
       cout << "Enter name for employee " << i + 1 << ": ";
       getline(cin, employee[i].name);
       cout << "Enter age for employee " << i + 1 << ": ";
       cin >> employee[i].age;
       cout << "Enter salary for employee " << i + 1 << ": ";
       cin >> employee[i].salary;     
       cin.ignore();  
   }

   displayData(employee, sizeOfEmployee);


}

void displayData(Employee employee[], int sizeOfEmployee) {

   cout << "DISPLAYING INFORMATION" << endl;

   for(int i = 0; i < sizeOfEmployee; i++) {
       cout << "Name: " << employee[i].name << endl;
       cout << "Age: " << employee[i].age << endl;
       cout << "Salary: " << employee[i].salary << endl;
   }

}

Thanks to all the people who helped me and provided me with answers. Very much appreciated as I'm still learning :))

Related