Question: IN C LANGUAGE: I've been trying to finish this program for the last few days, and I'm stuck on one part of it, and I
IN C LANGUAGE: I've been trying to finish this program for the last few days, and I'm stuck on one part of it, and I can't figure out what to do. The goal is to read in a file (separated by commas), put the information into a linked list, and then sort that linked list by either first or last name using function pointers. Everything I have so far works, aside from the fact that my output is never sorted. I'm doing something wrong with the listSort function, and I don't know what it is. Can anyone please just take a look at what I have and offer a suggestion or solution? It might not even be an issue with the function itself, but something somewhere else. I would greatly appreciate it. Please do not make any changes to the variables in the structs. Month has to be a string, it cannot be an integer.
driver.c:
#include "functions.h"
#include
#include
#include
#include
int main(int argc, char* argv[]) {
//creating input and output files
FILE* in = NULL;
FILE* out = NULL;
node_t* head = NULL;
node_t* temp = NULL;
//checking for 4 command line arguments
assert(argc == 4);
//opening input file
in = fopen(argv[1], "r");
assert(in != NULL);
//opening output file
out = fopen(argv[2], "w");
assert(out != NULL);
int sortBy = atoi(argv[4]);
temp = createList(in, &head);
if(sortBy == 1) {
sortList(&head, compare_by_firstname);
}
else if(sortBy == 2) {
sortList(&head, compare_by_lastname);
}
printList(out, temp);
deleteList(&head);
//closing files
fclose(in);
fclose(out);
return 0;
}
functions.c:
#include "functions.h"
#include
#include
#include
#include
#include
bool isLeapYear(int year) {
if(year % 4 != 0) {
return false;
}
else if(year % 100 != 0) {
return true;
}
else if(year % 400 != 0) {
return false;
}
else {
return true;
}
}
void printBorder(FILE* out)
{
int i = 0;
for(i = 0; i < 80; i++)
fprintf(out,"*");
fprintf(out, " ");
}
bool checkInvalidDate(node_t *node) {
int year = (int)node->birthday.year;
if(node->birthday.day < 1 || node->birthday.year < 1) {
return true;
}
if(strcmp(node->birthday.month, "February") == 0) {
if(isLeapYear(year)) {
if(node->birthday.day > 29) {
return true;
}
}
else if(node->birthday.day > 28) {
return true;
}
}
else if((strcmp(node->birthday.month, "April") == 0) || (strcmp(node->birthday.month, "June") == 0) ||
(strcmp(node->birthday.month, "September") == 0) || (strcmp(node->birthday.month, "November") == 0)) {
if(node->birthday.day > 30) {
return true;
}
}
else {
if(node->birthday.day > 31) {
return true;
}
}
return false;
}
void add(node_t **node, node_t **head) {
node_t* current = *head;
while(current != NULL) {
//comparing first and last names to check for duplicates; if duplicate the info isn't added to the list
if((strcmp(current->firstName, (*node)->firstName) == 0) && (strcmp(current->lastName, (*node)->lastName) == 0)) {
return;
}
current = current->next;
}
//adding information as a node to the list
(*node)->next = NULL;
if (*head == NULL) {
*head = *node;
}
else {
node_t* lastNode = *head;
while(lastNode->next != NULL) {
lastNode = lastNode->next;
}
lastNode->next = *node;
}
}
node_t* readNodeInfo(FILE* input) {
node_t* node = (node_t*)malloc(sizeof(node_t));
assert(node != NULL);
//scanning information using scansets and putting info in appropriate variables
fscanf(input, "%[^,], %[^,], %[^,], %d, %d, %[^,], %[^ ]", node->lastName, node->firstName, node->birthday.month,
&node->birthday.day, &node->birthday.year, node->major, node->standing);
return node;
}
node_t* createList(FILE* input, node_t** head) {
node_t* node = NULL;
node_t* temp = NULL;
char ch;
//scans through file and calls appropriate functions to read text and add nodes
while(!feof(input)) {
node = readNodeInfo(input);
if(!checkInvalidDate(node)) {
add(&node, head);
}
temp = node;
ch = fgetc(input);
}
return *head;
}
//prints the list of information to the output file
void printList(FILE* out, node_t* head) {
node_t* temp = head;
if(head == NULL) {
fprintf(stderr, "List is empty. ");
exit(1);
}
else {
printBorder(out);
fprintf(out, " List Info: ");
while(temp != NULL) {
fprintf(out, "Name:\t%s %s ", temp->firstName, temp->lastName);
fprintf(out, "Date of Birth:\t%s %d, %d ", temp->birthday.month, temp->birthday.day, temp->birthday.year);
fprintf(out, "Major:\t%s ", temp->major);
fprintf(out, "Year:\t%s ", temp->standing);
temp = temp->next;
}
printBorder(out);
}
}
//uses free() to delete the nodes in the list
void deleteList(node_t** head) {
node_t* temp = *head;
node_t* next = NULL;
while(temp != NULL) {
next = temp->next;
free(temp);
temp = next;
}
*head = NULL;
}
int compare_by_lastname(node_t *a, node_t *b)
{
return strcmp(a->lastName, b->lastName);
}
int compare_by_firstname(node_t *a, node_t *b)
{
return strcmp(a->firstName, b->firstName);
}
void sortList(node_t **head, fun_ptr comp) {
bool swapped = true;
node_t *ptr1 = *head;
node_t *ptr2 = NULL;
while(swapped) {
swapped = false;
ptr1 = *head;
while(ptr1->next != ptr2) {
if(comp(ptr1, ptr1->next) > 0) {
swapNode(&ptr1, &(ptr1->next));
swapped = true;
}
ptr1 = ptr1->next;
}
ptr2 = ptr1;
}
}
void swapNode(node_t** a, node_t** b) {
node_t *temp = *a;
*a = *b;
*b = temp;
}
functions.h:
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
#include
#include
#include "stdbool.h"
//add birthday struct here
typedef struct birthday {
int day;
int year;
char month[50];
} birthday_t;
//add node_t struct here (this struct will represent a node in the
//linked list)
typedef struct node {
char firstName[50];
char lastName[50];
birthday_t birthday;
char major[50];
char standing[50];
struct node *next;
} node_t;
//implement these:
/*Parameters: node - node of struct node
* head - head node of struct node, beginning of linked list
* Return: void
* This function adds a new node to the end of the linked list.
*/
void add(node_t **node, node_t **head);
bool checkInvalidDate(node_t *node);
/*Parameters: input - file pointer pointing to the input file where data is read
* when program is run.
* Return: node_t
* This function reads the information from the provided file and stores it in
* the appropriate variables in a node.
*/
node_t* readNodeInfo(FILE* input);
/*Parameters: input - file pointer pointing to the input file where data is read
* when program is run.
* head - head node of struct node, beginning of linked list
* Return: node_t
* This function calls add() and readNodeInfo() to read in information and then
* add that information to the linked list.
*/
node_t* createList(FILE*, node_t**);
/*Parameters: out - file pointer pointing to the output file where data is written to
* when program is run.
* head - head node of struct node, beginning of linked list
* Return: void
* This function prints the list of information to the output file.
*/
void printList(FILE*, node_t*);
/*Parameters: out - file pointer pointing to the output file where data is written to
* when program is run.
* Return: void
* This function prints the border of asterik's included as part of the output.
*/
void printBorder(FILE*);
/*Parameters: head - head node of struct node, beginning of linked list
* Return: void
* This function uses free() to delete the nodes in the linked list.
*/
void deleteList(node_t**);
typedef int(*fun_ptr)(node_t*, node_t*);
int compare_by_lastname(node_t*, node_t*);
int compare_by_firstname(node_t*, node_t*);
void sortList(node_t**, fun_ptr comp);
bool isLeapYear(int);
void swapNode(node_t** a, node_t** b);
#endif
Here is an example of what the info in the text file the program reads from looks like, for reference:
Kennedy,Leon,September,29,1998,CS/BS,Senior
Again, thank you. I greatly appreciate your help. I'm at a dead end.
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
