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++)
< < previous    next > >