Complementary task for topic: 9
M Nemeth � 2023-08-29 15:21:04.631218'
File Handling: read CSV
File Handling: read CSV
HARD!
Write a C program that reads a CSV (Comma-Separated Values) file named "data.csv" containing information about employees in a company. Each row in the file represents an employee and is formatted as follows: "EmployeeID, Name, Age, Salary".
The program should read the file, store the information about each employee in a dynamic array of structures, and then perform the following tasks:
Calculate the total salary of all employees and write it to a new text file named "total_salary.txt".
Find and write the names of the top 5 highest-paid employees to a new text file named "highest_paid.txt".
Find and write the names of the 5 youngest employees to a new text file named "youngest_employees.txt".
Find and write the names of the 5 oldest employees to a new text file named "oldest_employees.txt".
data.csv:
101, John Doe, 30, 50000
102, Jane Smith, 28, 55000
103, Michael Johnson, 35, 60000
104, Emily Brown, 32, 52000
105, James Lee, 25, 48000
106, Sarah Wilson, 40, 65000
Hint: The getline function can read an entire line at once, that can be processed later. The usage:
while ((read = getline(&line, &len, inputFile)) != -1) {
// Process the line here
// ...
// Print the line for demonstration purposes
printf("Line: %s", line);
}
Employees should dynamically increased.
Solution
#include
#include
typedef struct {
int EmployeeID;
char Name[50];
int Age;
int Salary;
} Employee;
int main() {
FILE *inputFile, *outputFile;
char *line = NULL;
size_t len = 0;
ssize_t read;
Employee *employees = NULL;
int numEmployees = 0;
int totalSalary = 0;
// Open the input file in read mode
inputFile = fopen("data.csv", "r");
// Check if the file was opened successfully
if (inputFile == NULL) {
printf("Error opening the input file.\n");
return 1;
}
// Read each line from the input file
while ((read = getline(&line, &len, inputFile)) != -1) {
// Parse the line to extract employee data
Employee emp;
sscanf(line, "%d, %[^,], %d, %d",
&emp.EmployeeID, emp.Name,
&emp.Age, &emp.Salary);
// Update total salary
totalSalary += emp.Salary;
// Add the employee to the array
numEmployees++;
employees = (Employee*)realloc(employees, numEmployees * sizeof(Employee));
employees[numEmployees - 1] = emp;
}
// Close the input file
fclose(inputFile);
// Open the output file to write total salary
outputFile = fopen("total_salary.txt", "w");
// Check if the file was opened successfully
if (outputFile == NULL) {
printf("Error opening the output file.\n");
return 1;
}
// Write the total salary to the output file
fprintf(outputFile, "Total Salary: %d\n", totalSalary);
// Close the output file
fclose(outputFile);
// Sort employees based on salary (highest to lowest)
for (int i = 0; i < numEmployees - 1; i++) {
for (int j = i + 1; j < numEmployees; j++) {
if (employees[i].Salary < employees[j].Salary) {
Employee temp = employees[i];
employees[i] = employees[j];
employees[j] = temp;
}
}
}
// Open the output file to write the names of the top 5 highest-paid employees
outputFile = fopen("highest_paid.txt", "w");
// Check if the file was opened successfully
if (outputFile == NULL) {
printf("Error opening the output file.\n");
return 1;
}
// Write the names of the top 5 highest-paid employees to the output file
fprintf(outputFile, "Top 5 Highest-Paid Employees:\n");
for (int i = 0; i < 5 && i < numEmployees; i++) {
fprintf(outputFile, "%d. %s\n", i + 1, employees[i].Name);
}
// Close the output file
fclose(outputFile);
// Find the youngest and oldest employees
int youngestIndex = 0;
int oldestIndex = 0;
for (int i = 1; i < numEmployees; i++) {
if (employees[i].Age < employees[youngestIndex].Age) {
youngestIndex = i;
}
if (employees[i].Age > employees[oldestIndex].Age) {
oldestIndex = i;
}
}
// Open the output file to write the names of the youngest employees
outputFile = fopen("youngest_employees.txt", "w");
// Check if the file was opened successfully
if (outputFile == NULL) {
printf("Error opening the output file.\n");
return 1;
}
// Write the names of the youngest employees to the output file
fprintf(outputFile, "Top 5 Youngest Employees:\n");
for (int i = 0; i < 5 && i < numEmployees; i++) {
fprintf(outputFile, "%d. %s\n", i + 1, employees[youngestIndex + i].Name);
}
// Close the output file
fclose(outputFile);
// Open the output file to write the names of the oldest employees
outputFile = fopen("oldest_employees.txt", "w");
// Check if the file was opened successfully
if (outputFile == NULL) {
printf("Error opening the output file.\n");
return 1;
}
// Write the names of the oldest employees to the output file
fprintf(outputFile, "Top 5 Oldest Employees:\n");
for (int i = 0; i < 5 && i < numEmployees; i++) {
fprintf(outputFile, "%d. %s\n", i + 1, employees[oldestIndex + i].Name);
}
// Close the output file
fclose(outputFile);
// Free dynamically allocated memory
free(employees);
free(line);
return 0;
}
Explanation
line-by-line: ```c #include#include ``` - We include the necessary standard header files `stdio.h` and `stdlib.h` for input/output functions and dynamic memory allocation, respectively. ```c typedef struct { int EmployeeID; char Name[50]; int Age; int Salary; } Employee; ``` - We define a `struct` called `Employee` that represents the data of an employee, including `EmployeeID`, `Name`, `Age`, and `Salary`. ```c int main() { FILE *inputFile, *outputFile; char *line = NULL; size_t len = 0; ssize_t read; Employee *employees = NULL; int numEmployees = 0; int totalSalary = 0; ``` - We declare the necessary variables, including file pointers `inputFile` and `outputFile`, a pointer `line` to hold the dynamically allocated line read from the input file, and a variable `len` to store the length of the line. We also declare an array of `Employee` structs called `employees`, an integer `numEmployees` to keep track of the number of employees, and an integer `totalSalary` to store the sum of all employee salaries. ```c inputFile = fopen("data.csv", "r"); if (inputFile == NULL) { printf("Error opening the input file.\n"); return 1; } ``` - We open the input file "data.csv" in read mode using `fopen()`. If the file opening fails, we print an error message and return with an error code. ```c while ((read = getline(&line, &len, inputFile)) != -1) { // Parse the line to extract employee data Employee emp; sscanf(line, "%d, %[^,], %d, %d", &emp.EmployeeID, emp.Name, &emp.Age, &emp.Salary); ``` - We use `getline()` to read each line from the input file. The function will allocate memory for the line dynamically and update the `line` and `len` variables accordingly. The loop continues until `getline()` returns `-1`, indicating the end of the file has been reached. Inside the loop, we use `sscanf()` to parse the line and extract the `EmployeeID`, `Name`, `Age`, and `Salary` fields into a temporary `Employee` struct `emp`. ```c totalSalary += emp.Salary; ``` - We update the `totalSalary` by adding the salary of the current employee `emp` to it. ```c numEmployees++; employees = (Employee*)realloc(employees, numEmployees * sizeof(Employee)); employees[numEmployees - 1] = emp; ``` - We increment the `numEmployees` counter and dynamically reallocate memory for the `employees` array using `realloc()` to accommodate the new employee. We store the `emp` struct in the last position of the `employees` array. ```c } ``` ```c fclose(inputFile); ``` - We close the input file after reading all the lines. ```c outputFile = fopen("total_salary.txt", "w"); if (outputFile == NULL) { printf("Error opening the output file.\n"); return 1; } ``` - We open an output file called "total_salary.txt" in write mode using `fopen()`. If the file opening fails, we print an error message and return with an error code. ```c fprintf(outputFile, "Total Salary: %d\n", totalSalary); ``` - We write the total salary to the output file using `fprintf()`. ```c fclose(outputFile); ``` - We close the output file after writing the total salary. ```c for (int i = 0; i < numEmployees - 1; i++) { for (int j = i + 1; j < numEmployees; j++) { if (employees[i].Salary < employees[j].Salary) { Employee temp = employees[i]; employees[i] = employees[j]; employees[j] = temp; } } } ``` - We sort the `employees` array based on salary in descending order using the selection sort algorithm. ```c outputFile = fopen("highest_paid.txt", "w"); if (outputFile == NULL) { printf("Error opening the output file.\n"); return 1; } ``` - We open another output file called "highest_paid.txt" in write mode. ```c fprintf(outputFile, "Top 5 Highest-Paid Employees:\n"); for (int i = 0; i < 5 && i < numEmployees; i++) { fprintf(outputFile, "%d. %s\n", i + 1, employees[i].Name); } ``` - We write the names of the top 5 highest-paid employees to the "highest_paid.txt" file. ```c fclose(outputFile); ``` - We close the "highest_paid.txt" file. ```c int youngestIndex = 0; int oldestIndex = 0; for (int i = 1; i < numEmployees; i++) { if (employees[i].Age < employees[youngestIndex].Age) { youngestIndex = i; } if (employees[i].Age > employees[oldestIndex].Age) { oldestIndex = i; } } ``` - We find the indices of the youngest and oldest employees in the `employees` array. ```c outputFile = fopen("youngest_employees.txt", "w"); if (outputFile == NULL) { printf("Error opening the output file.\n"); return 1; } ``` - We open another output file called "youngest_employees.txt" in write mode. ```c fprintf(outputFile, "Top 5 Youngest Employees:\n"); for (int i = 0; i < 5 && youngestIndex + i < numEmployees; i++) { fprintf(outputFile, "%d. %s\n", i + 1, employees[youngestIndex + i].Name); } ``` - We write the names of the top 5 youngest employees to the "youngest_employees.txt" file. ```c fclose(outputFile); ``` - We close the "youngest_employees.txt" file. ```c outputFile = fopen("oldest_employees.txt", "w"); if (outputFile == NULL) { printf("Error opening the output file.\n"); return 1; } ``` - We open another output file called "oldest_employees.txt" in write mode. ```c fprintf(outputFile, "Top 5 Oldest Employees:\n"); for (int i = 0; i < 5 && oldestIndex + i < numEmployees; i++)