load list from file in c - c

I am unable to correctly specify the end of my list. I am not sure why but I think its because the condition of the while loop is allowing node to take data from memory and then making its next = NULL. I tried to replace node->next = NULL; with node = NULL; but it didn't work. I will be very happy to receive some helpful solutions or tips and thank you in advance.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
//my variables
typedef struct {
char Fname[len];
char Lname[len];
double salary;
} employee;
// list of employees
typedef struct list {
employee e;
struct list *next;
} list;
void LOAD_LIST(FILE *f, list *head)
{
list *node = (list *)malloc(sizeof(list));
node = head;
while (fscanf(f, "%10s%10s%lf", node->e.Fname, node->e.Lname, &node->e.salary) != EOF)
{
node->next = (list *)malloc(sizeof(list));
if (node->next == NULL)
{
printf("memory allocation failed\n");
break;
}
node = node->next;
}
node->next = NULL;
}
void DISPLAY(list *node)
{
while (node != NULL)
{
printf("%s | %s | %.2lf\n", node->e.Fname, node->e.Lname, node->e.salary);
node = node->next;
}
}
void freeList(struct list *head)
{
list *tmp;
while (head != NULL)
{
tmp = head;
head = head->next;
free(tmp);
}
}
int main()
{
FILE *file = fopen("file.txt", "r");
list *listhead = (list *)malloc(sizeof(listhead));
LOAD_LIST(file, listhead);
DISPLAY(listhead);
freeList(listhead);
fclose(file);
return 0;
}
EDIT: Thanks for the responses I corrected the problem you pointed to but I still don't know how to free the node that got EOF.
Here is the new function:
void LOAD_LIST(FILE *f, list *head)
{
list *node = (list *)malloc(sizeof(list));
fscanf(f, "%10s%10s%lf", head->e.Fname, head->e.Lname, &head->e.salary);
head->next = node;
while (fscanf(f, "%10s%10s%lf", node->e.Fname, node->e.Lname, &node->e.salary) != EOF)
{
node->next = (list *)malloc(sizeof(list));
if (node->next == NULL)
{
printf("memory allocation failed\n");
break;
}
node = node->next;
}
node->next = NULL;
}

I think there are a few problems in your code:
You're always allocating the head of the linked list in main(), what if your file is empty and no data is parsed via file. I think you should modify your LOAD_LIST method to return the new list head instead.
In while loop of your LOAD_LIST method, you're allocating list *node before reading using fscanf. This means you have an extra node allocated no matter what happens during fscanf. I think you should allocate memory after reading via fscanf check whether number of characters parsed is equal to 3.
Not sure why, but you're allocating memory of node->next while you're reading contents of node. What if it's the last line of file you're reading. You'll have an extra node in the end.
I moved your node memory allocation+initialization logic to a method createNewNode and I'm tracking head and prevNode variables to keep track of beginning and last allocated node of your linked list:
list* createNewNode(char firstName[], char lastName[], double salary) {
list* newNode = (list *) malloc(sizeof(list));
if (newNode == NULL) {
printf("Node Memory allocation failed\n");
return NULL;
}
strcpy(newNode->e.fName, firstName);
strcpy(newNode->e.lName, lastName);
newNode->e.salary = salary;
newNode->next = NULL;
}
list* load_list(FILE *f)
{
list *head = NULL, *prevNode = NULL;
char firstName[100], lastName[100];
double salary;
while (fscanf(f, "%10s%10s%lf", firstName, lastName, &salary) == 3) {
list *currentNode = createNewNode(firstName, lastName, salary);
if (currentNode == NULL) {
printf("memory allocation failed\n");
break;
}
if (head == NULL) {
head = currentNode;
prevNode = currentNode;
} else {
prevNode->next = currentNode;
prevNode = currentNode;
}
}
return head;
}
// ...
int main() {
FILE *file = fopen("file.txt", "r");
list* listhead = load_list(file);
display(listhead);
freeList(listhead);
fclose(file);
return 0;
}
I tested with a file like this:
Rohan Kumar 100
Robert Dicosta 200
Rupert Griffin 30
BadInput
This gives the following output:
c-posts : $ ./a.out
Rohan | Kumar | 100.00
Robert | Dicosta | 200.00
Rupert | Griffin | 30.00

Related

I need to create a single linked list by taking the input from a file i.e., .txt file and print the linked list

The .txt file consists of id, name, gender, occupation, age. Now I need to read from the file and create a linked list and print the list. The code should be in C language.
below is the code which I am trying, but only a string/ word is printing.
Do I need to use fscanf function in while loop instead of fgets function? I need to print all the contents of text file, which has both integer and character type in it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct list {
char *string;
struct list *next;
};
typedef struct list LIST;
int main(void) {
FILE *fp;
char line[128];
LIST *current, *head;
head = current = NULL;
fp = fopen("hello.txt", "r");
while(fgets(line, sizeof(line), fp)){
LIST *node = malloc(sizeof(LIST));
node->string = strdup(line);
node->next =NULL;
if(head == NULL){
current = head = node;
} else {
printf("%s", current->string);
current = current->next = node;
}
}
fclose(fp);
for(current = head; current ; current=current->next){
// printf("%s", current->string);
}
return 0;
}
This is wrong since it will never print the last line you read:
if(head == NULL){
current = head = node;
} else {
printf("%s", current->string); // prints the previous line
current = current->next = node;
}
If you want all lines to be printed, do the printing after you've assigned current:
if(head == NULL){
current = head = node;
} else {
current = current->next = node;
}
printf("%s", current->string);
Or before assigning current, using node:
printf("%s", node->string);
if(head == NULL){
current = head = node;
} else {
current = current->next = node;
}
I would also suggest organizing the code and make use of functions.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct list LIST;
struct list {
char *string;
LIST *next; // I moved the typedef above the struct list definition
};
// A function to read and populate a list from a stream:
LIST *list_read(FILE *fp) {
char line[128];
LIST *head, **tail = &head;
while (fgets(line, sizeof line, fp)) {
LIST *node = malloc(sizeof *node);
node->string = strdup(line);
// simplification of your `if(head == NULL)` code. No `if`s needed:
*tail = node;
tail = &node->next;
}
*tail = NULL;
return head;
}
// A function to free the resources allocated by a list
void list_free(LIST *head) {
for (LIST *current = head, *next; current; current = next) {
next = current->next;
free(current->string);
free(current);
}
}
// A function to print a list
void list_print(LIST *head) {
for (LIST *current = head; current; current = current->next) {
printf("%s", current->string);
}
}
int main(void) {
FILE *fp = fopen("hello.txt", "r");
if (fp == NULL) return 1;
LIST *head = list_read(fp);
fclose(fp);
list_print(head);
list_free(head);
}
If you want the list to be sorted in alphabetical order, you could add a function that inserts a node in the correct position in the list:
void list_insert(LIST **lp, char *str) {
LIST *node = malloc(sizeof *node);
node->string = strdup(str);
// find insertion point for the list to be in alphabetical order
while(*lp && strcmp(str, (*lp)->string) > 0) {
lp = &(*lp)->next;
}
// link the new node:
node->next = *lp;
*lp = node;
}
and change list_read accordingly:
LIST *list_read(FILE *fp) {
char line[128];
LIST *head = NULL;
while (fgets(line, sizeof line, fp)) {
list_insert(&head, line);
}
return head;
}

I have a problem with a problem that uses lists

I have a problem with this code. I have tried to debug with gdb and Valgrind, But nothing works...
The goal of the code is to create a list, where every string is added only if no existing node with the same string in already part of the list.
This is the code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct node {
char *word;
struct node *next;
};
void print_list(struct node *head) {
while ((head) != NULL) {
printf(" %s -> ", head->word);
head = (head->next);
}
}
// insert a new node in head
void add_n(struct node **head, char *str) {
struct node *new;
new = malloc(sizeof(struct node));
if (new == NULL) {
printf("Not enough memory\n");
exit(EXIT_FAILURE);
}
new->word = str;
new->next = NULL;
if ((*head) == NULL){
(*head) = new;
}
while ((*head)->next != NULL) {
head = &(*head)->next;
}
(*head)->next = new;
}
// check if str is present in the list
int find_string(struct node **head, char *str) {
int found = 0;
while ((*head) != NULL) {
int i = strcmp(str, (*head)->word); //i=0 are the same
if (i == 0) {
found = 1;
return found;
}
head = &((*head)->next);
}
return found;
}
// insert a new string in the list only if is new
void insert(struct node **head, char *str) {
if (find_string(head, str) == 0) {
add_n(head, str);
}
}
void rem_ent(struct node **head, struct node *ent) {
while ((*head) != ent) {
head = &((*head)->next);
}
(*head) = ent->next;
free(ent);
}
void fini_list(struct node **head) {
while ((*head) != NULL) {
rem_ent(head, *head);
head = &((*head)->next);
}
}
int main() {
struct node *head = NULL;
insert(&head, "electric");
print_list(head);
insert(&head, "calcolatori");
print_list(head);
insert(&head, "prova pratica");
print_list(head);
insert(&head, "calcolatori");
print_list(head);
fini_list(&head);
//printf("lunghezza media = %f\n", avg_word_lenght(head));
return 0;
}
Maybe the error might be stupid, but I spent a lot of time debugging without success.
the function fini_list invokes undefined behavior due to the redundant statement
head=&((*head)->next);
because the function rem_ent already set the new value of the pointer head.
void rem_ent(struct node** head, struct node * ent){
while((*head) != ent){
head= &((*head)->next);
}
(*head)= ent->next;
free(ent);
}
Remove the statement
void fini_list(struct node** head){
while((*head) != NULL){
rem_ent(head, *head);
}
}
Also change the function add_n the following way
// insert a new node in head
void add_n(struct node ** head, char* str){
struct node * new;
new = malloc(sizeof(struct node));
if (new == NULL) {
printf("Not enough memory\n");
exit(EXIT_FAILURE);
}
new->word= str;
new->next = NULL;
if ((*head)==NULL){
(*head)=new;
}
else
{
while((*head)->next != NULL){
head = &(*head)->next;}
(*head)->next = new;
}
}
And next time format the code such a way that it would be readable.
In general you should allocate dynamically memory for strings that will be stored in nodes of the list.

Something wrong with strcmp?

My assignment is to read a file in to a linked list. The file contains a name and a letter indicating what to do with the name, either add or delete from list. The file is in this format:
Kathy a
Beverly a
Chuck a
Radell a
Gary a
Roger d
and so on...
The problem comes when i try to split up the name and the operation. The strcmp() doesn't even recognize the op_code variable in my code. I printed out both the name and the op_code and they print right unless i put a character near the op_code.
Here's my code:
//Tristan Shepherd
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
char name[42];
struct node *next;
};
void printList(struct node *head)
{
struct node *current = head;
while (current)
{
printf("3 %s\n", current->name);
current = current->next;
}
}
void addFront(struct node **head, char *newname)
{
struct node* newnode = (struct node*)malloc(sizeof(struct node));
strcpy(newnode->name, newname);
newnode->next = (*head);
(*head) = newnode;
}
void delete(struct node **head, char *namedelete)
{
struct node* temp = *head, *prev;
if (temp != NULL && temp->name == namedelete)
{
*head = temp->next;
free(temp);
return;
}
while (temp != NULL && temp->name != namedelete)
{
prev = temp;
temp = temp->next;
}
if (temp == NULL) return;
prev->next = temp->next;
free(temp);
}
void readfile(struct node *head)
{
FILE *file = fopen("hw8.data", "r");
char tname[42];
char *tempname = (char*)malloc(42*sizeof(char));
char *op_code = (char*)malloc(1*sizeof(char));
while(fgets(tname, sizeof(tname), file))
{
tempname = strtok(tname, " ");
op_code = strtok(NULL, "\n");
printf("%s\n", tempname);
printf("%s\n", op_code);
if (!strcmp(op_code, "a"))
{
addFront(&head, tempname);
}
else if (!strcmp(op_code, "d"))
{
delete(&head, tempname);
}
}
fclose(file);
printList(head);
}
int main()
{
struct node *head = NULL;
readfile(head);
exit(0);
}
The only issue I see with in readFile() is a memory leak.
char *tempname = (char*)malloc(42*sizeof(char));
char *op_code = (char*)malloc(1*sizeof(char));
should just be
char *tempname;
char *op_code;
strtok() breaks up the string in place, it does not produce a copy of the string, so no need to allocate extra memory.
I do see some issues in delete() however
You should be using strcmp() here instead of ==, like you do in readfile()
if (temp != NULL && temp->name == namedelete)
while (temp != NULL && temp->name != namedelete)
You may also need to initialize prev.
With your code as-is, add seemed to be working fine, and with my changes, delete looks ok.

FILE reading and sorting a link list

It seems my FILE reading function is slightly off. Instead of printing all the data (First Name: Last Name: priority: Reading Level:) per entry when I call my print function it stops after two and just has the skeleton of what needs to be printed there for the last three entries. And because of that, when I then call my sort function based off priority level in each struct link list, I can't tell if it's printing correctly.
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#define NAME 25
#define TITLE 50
typedef struct Book{
int bookID;
char* title;
bool checkedOut;
struct Book* next;
}book;
typedef struct Student{
char* firstName;
char* lastName;
int priority;
int readingLevel;
book* backPack;
bookids* wishlist;
struct Student* next;
}student;
student* buildStudentList(char* studentFile, student* head)
{
FILE *cfptr=fopen(studentFile, "r");
if(cfptr==NULL){
printf("\nFIle could not be opened\n");
return 0;
}
if(head==NULL){
head=malloc(sizeof(student));
head->next=NULL;
head->firstName=malloc(sizeof(student)*35);
head->lastName=malloc(sizeof(student)*35);
fscanf(cfptr,"%s %s %d %d", head->firstName,head->lastName,
&head->priority, &head->readingLevel);
}
student* current=head;
while(current->next!=NULL){
current=current->next;
}
current->next=malloc(sizeof(student));
current=current->next;
current->firstName=malloc(sizeof(student)*35);
current->lastName=malloc(sizeof(student)*35);
while( fscanf(cfptr, "%s %s %d %d", current->firstName, current->lastName,
&current->priority, &current->readingLevel)!=EOF){
student* current=head;
while(current->next!=NULL){
current=current->next;
}
current->next=malloc(sizeof(student));
current=current->next;
current->firstName=malloc(sizeof(student)*35);
current->lastName=malloc(sizeof(student)*35);
}
return head;
}
void createPriorityQueue(student* head)
{
if(head==NULL ||head->next==NULL){
return;
}
student* curr; student* largest; student* largestPrev; student* prev;
curr=head;
largest=head;
prev=head;
largestPrev=head;
while(curr!=NULL){
if(&curr->priority>&largest->priority){
largestPrev=prev;
largest=curr;
}
prev=curr;
curr=curr->next;
}
student* tmp;
if(largest!=head)
{
largestPrev->next=head;
tmp=head->next;
head->next=tmp;
}
}
There are a few bugs.
The malloc for allocation of strings should be malloc(35) and not malloc(sizeof(student) * 35). It won't crash but it's wasteful.
Your build function was way too complicated and had several bugs--I had to recode it.
Your priority queue function was comparing addresses of priority instead of values [what we want].
Anyway, here's your code with some annotations for the bugs and a recoded create function [please pardon the gratuitous style cleanup]:
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#define NAME 25
#define TITLE 50
typedef struct Book {
int bookID;
char *title;
bool checkedOut;
struct Book *next;
} book;
typedef struct Student {
char *firstName;
char *lastName;
int priority;
int readingLevel;
book *backPack;
bookids *wishlist;
struct Student *next;
} student;
// NOTE/BUG: this function is way to complicated -- see below for a simpler one
student *
buildStudentList(char *studentFile, student * head)
{
FILE *cfptr = fopen(studentFile, "r");
if (cfptr == NULL) {
printf("\nFIle could not be opened\n");
return 0;
}
if (head == NULL) {
head = malloc(sizeof(student));
head->next = NULL;
// NOTE/BUG: we want just enough to store strings -- this is true for all the
// other mallocs that allocate names
#if 0
head->firstName = malloc(sizeof(student) * 35);
head->lastName = malloc(sizeof(student) * 35);
#else
head->firstName = malloc(35);
head->lastName = malloc(35);
#endif
fscanf(cfptr, "%s %s %d %d",
head->firstName, head->lastName, &head->priority,
&head->readingLevel);
}
student *current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = malloc(sizeof(student));
current = current->next;
current->firstName = malloc(sizeof(student) * 35);
current->lastName = malloc(sizeof(student) * 35);
while (fscanf(cfptr, "%s %s %d %d",
current->firstName, current->lastName, &current->priority,
&current->readingLevel) != EOF) {
student *current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = malloc(sizeof(student));
current = current->next;
current->firstName = malloc(sizeof(student) * 35);
current->lastName = malloc(sizeof(student) * 35);
}
// NOTE/BUG: close input file
#if 1
fclose(cfptr);
#endif
return head;
}
// simplified version
student *
buildStudentList(char *studentFile, student * head)
{
FILE *cfptr = fopen(studentFile, "r");
student *current;
student *tail;
char firstName[5000];
char lastName[5000];
if (cfptr == NULL) {
printf("\nFIle could not be opened\n");
return 0;
}
// find last element in list
tail = NULL;
for (current = head; current != NULL; current = current->next)
tail = current;
while (1) {
// allocate new node
current = malloc(sizeof(student));
// initialize the next pointer (in a singly linked list, this is nulled)
current->next = NULL;
// get data for new node
if (fscanf(cfptr, "%s %s %d %d",
firstName, lastName, &current->priority,
&current->readingLevel) == EOF) {
free(current);
break;
}
// allocate space for strings
current->firstName = strdup(firstName);
current->lastName = strdup(lastName);
// add to empty list
if (head == NULL)
head = current;
// add to tail of list
else
tail->next = current;
// set this as new tail of list
tail = current;
}
fclose(cfptr);
return head;
}
void
createPriorityQueue(student * head)
{
if (head == NULL || head->next == NULL) {
return;
}
student *curr;
student *largest;
student *largestPrev;
student *prev;
curr = head;
largest = head;
prev = head;
largestPrev = head;
while (curr != NULL) {
// NOTE/BUG: this compares _addresses_ but we want to compare values
#if 0
if (&curr->priority > &largest->priority) {
#else
if (curr->priority > largest->priority) {
#endif
largestPrev = prev;
largest = curr;
}
prev = curr;
curr = curr->next;
}
student *tmp;
if (largest != head) {
largestPrev->next = head;
tmp = head->next;
head->next = tmp;
}
}
UPDATE:
how do I make the createpriority function sort in the opposite order, its form highest to lowest, i need lowest to highest?
Not sure exactly which order you want now or what changes you've already made. In your original code, you were only doing a single pass on the list instead of as many passes as there were elements.
I've fixed the original code to do the correct number of passes, using simple insertion/selection. This is slow. You could speed it up by doing a mergesort on the linked list, but that's more involved.
Anyway, here's the code. I didn't test it or even compile it but it should get you closer:
student *
createPriorityQueue(student *head)
{
student *curr;
student *bestCurr;
student *bestPrev;
student *prev;
student *tail;
student *rtn;
// initialize sorted list
rtn = NULL;
tail = NULL;
// process all elements of unsorted list
while (head != NULL) {
// assume head of unsorted list is best priority in unsorted list
bestCurr = head;
bestPrev = NULL;
// find best in unsorted list
prev = NULL;
for (curr = head; curr != NULL; curr = curr->next) {
#ifdef SORT_LOW_TO_HIGH
if (curr->priority < bestCurr->priority) {
bestCurr = curr;
bestPrev = prev;
}
#else
if (curr->priority > bestCurr->priority) {
bestCurr = curr;
bestPrev = prev;
}
#endif
prev = curr;
}
// remove element from unordered list
if (bestPrev != NULL)
bestPrev->next = bestCurr->next;
else
head = bestCurr->next;
// add the next best priority to the end of the ordered list
if (tail != NULL)
tail->next = bestCurr;
else
rtn = bestCurr;
// set new tail of ordered list
tail = bestCurr;
tail->next = NULL;
}
return rtn;
}

C Programming - Sorting structs as they enter your linked list

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_ENTRY 100
//define struct
typedef struct StudentRecords
{
int StudentID; //must be of size 7 between 1000000 and 9999999
char *Firstname; //= MALLOC(256*sizeof(char)); // must be any length and allocate memory dynamically.
char *Lastname; //= MALLOC(256*sizeof(char));
char *Department; //= MALLOC(256*sizeof(char));
float GPA; // must be between 0 and 4
} STUDENTRECORDS;
//define linked list structs
struct Node
{
struct StudentRecords data;
struct Node* next;
struct Node* prev;
};
//define global head
struct Node* head;
struct Node* GetNewNode(struct StudentRecords Record)
{
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = Record;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
//create a function to use the struct
void Insert(struct StudentRecords Record)
{
struct Node* newNode = GetNewNode(Record);
if (head==NULL)
{
head = newNode;
return;
}
head->prev = newNode;
newNode->next = head;
head= newNode;
}
void Print() {
struct Node* temp = head;
printf("StudentID: ");
while (temp != NULL)
{
printf("%d\n", temp->data.StudentID);
temp = temp->next;
}
}
void ReversePrint()
{
struct Node* temp = head;
if (temp == NULL)
{
return;
}
while (temp->next != NULL)
{
temp = temp->next;
}
printf("Reverse: ");
while (temp!= NULL)
{
printf("%d", temp->data);
temp = temp->prev;
}
printf("\n");
}
int main()
{
/*
First job is read the file
*/
//set variables
int i=0;
char filecontent, file_name[100];
FILE *fp;
STUDENTRECORDS StudentRecords[MAX_ENTRY];
for(i=0;i<MAX_ENTRY;i++)
{
StudentRecords[i].Firstname = malloc(sizeof(char)*256);
StudentRecords[i].Lastname = malloc(sizeof(char)*256);
StudentRecords[i].Department = malloc(sizeof(char)*256);
}
printf("Enter directory of file\n"); // instructs user to enter directory of file
gets(file_name); //prompt use
fp = fopen(file_name,"r"); //opens the file "r" is read mode for fopen()
// here is a check to see if fp is empty and throw an error if so
if (fp == NULL)
{
perror("Could not open file\n");
//exit(EXIT_FAILURE);
}
//this adds the content to the struct we created.
// and prints it
i=0;
printf("Records in struct:\n");
while(EOF!=fscanf(fp, "%d %s %s %s %f\n", &StudentRecords[i].StudentID, StudentRecords[i].Firstname, StudentRecords[i].Lastname, StudentRecords[i].Department, &StudentRecords[i].GPA))
{
printf("%d %s %s %s %f\n", StudentRecords[i].StudentID, StudentRecords[i].Firstname, StudentRecords[i].Lastname, StudentRecords[i].Department, StudentRecords[i].GPA);
i++;
}
printf("Creating linked list of structs...\n");
//Now we have to add it to a linked list.
for (i=0; i < sizeof(StudentRecords)/sizeof(StudentRecords[0]); i++)
Insert(StudentRecords[i]);
//Insert(StudentRecords[0]);
//Insert(StudentRecords[1]);
//print function for linked list
printf("Printing linked list...\n");
Print();
// fclose() must follow an fopen()
fclose(fp);
return 0;
}
Here is my entire code for a program I'm writing. I am to input a text file that looks like this:
2040003 AAAA BBBBBBBBB ComputerScience 3.4
2040002 AAA CCC ElectricalEngineering 3.01
2040005 AAAAAAAAAAAAAAAAA BBB ComputerScience 3.60
The output is to be sorted the the first int, or StudentID and separated by commas
2040002,AAA,CCC,ElectricalEngineering,3.01
2040003,AAAA,BBBBBBBBB,ComputerScience,3.45
2040005,AAAAAAAAAAAAAAAAA,BBB,ComputerScience,3.60
I was thinking of sorting the structs as they enter the linked list, rather than after. I think I can alter my Insert() function to place them in the right order, but everything I've tried hasn't worked. So here's the code with it simply printing the list without any sorting.
Thanks for any suggestions or pointers.
Your insert function should look something like this
void Insert(struct StudentRecords Record)
{
struct Node* newNode = GetNewNode(Record);
struct Node *tmp = head;
/* Check if we need to insert at head */
if (head==NULL)
{
head = newNode;
return;
}
/* Check if new node is smaller than head */
if (head->data.StudentID > Record.StudentID) {
head->prev = newNode;
newNode->next = head;
head = newNode;
return;
}
/* Find the node previous to node having StudentID > "StudentID in new node" */
while(tmp->next && tmp->next->data.StudentID < Record.StudentID)
tmp = tmp->next;
/* Insert the new node */
newNode->next = tmp->next;
if (tmp->next)
tmp->next->prev = newNode;
tmp->next = newNode;
newNode->prev = tmp;
}

Resources