Trouble printing linked list elements in C - c

I am trying to create a print function for my linked list program.
Here is my code so far, the only printing I managed to do is within my readfile function. I have no idea how to use a function to print linked list elements.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct record { // to contain several data types
char process;
char state;
int NUT;
int AT;
int Prio;
struct reord *next;
};
typedef struct record node;
void readfile(node *newlist, node *ncurr, node *next, int quanta, int readincrement, int newincrement, int procnumb, char *fn);
node *crtnode();
main() {
int menu = 0, quanta, readincrement, newincrement, procnumb;
char fn[100];
node *newlist = NULL;
node *ncurr = NULL;
node *next =NULL;
char process, state;
int NUT, AT, Prio;
do {
printf("Selfish RR Algorathim\n");
printf("Enter 1 for existing file\n");
printf("Enter 2 for manual input\n");
printf("Enter 3 for random\n");
printf("Enter 4 for exit\n");
scanf("%d", &menu);
switch (menu) {
case 1:
printf("insert file name");
scanf("%s", &fn);
readfile(newlist, ncurr, next, quanta, readincrement, newincrement, procnumb, fn);
break;
case 2:
printf("boo");
break;
case 3:
printf("haha");
break;
default:
printf("Wrong choice again");
break;
}
} while (menu != 4);
}
void readfile(node *newlist, node *ncurr, node *next, int quanta, int readincrement, int newincrement, int procnumb, char *fn) {
FILE *myFile;
int t;
int j, i;
newlist = NULL;
myFile = fopen(fn, "r");
// reading the values that will be final through out this process
fscanf(myFile, "%d", &quanta);
fscanf(myFile, "%d", &newincrement);
fscanf(myFile, "%d", &readincrement);
fscanf(myFile, "%d", &procnumb);
printf("quanta = %d newinc = %d Readyinc = %d procnumb = %d \n", quanta, newincrement, readincrement, procnumb);
newlist = crtnode(); // creating memory locations for the new list
ncurr = newlist;
for (i = 0; i < procnumb; i++) {
ncurr->process = 'A' + i;
ncurr->state = '-';
fscanf(myFile, "%d", &ncurr->NUT);
fscanf(myFile, "%d", &ncurr->AT);
ncurr->Prio = '\0';
if (i <= procnumb - 1) {
ncurr->next = crtnode();
ncurr = ncurr->next;
}
}
ncurr = newlist;
for (i = 0; i < procnumb; i++) {
printf("\nnode = %p proc = %c state = %c NUT = %d AT = %d priority = %d nextnode = %p\n", ncurr, ncurr->process, ncurr->state, ncurr->NUT, ncurr->AT, ncurr->Prio, ncurr->next);
ncurr = ncurr->next;
}
fclose(myFile);
}
node *crtnode() {
return((node *)malloc(sizeof(node)));
}

Related

im trying to read data from a file and disturb them into linked nodes, however, when i check the linked nodes it says it's empty

So what I'm trying to do is read inputs from a file and disturb the input into nodes, after that I link the nodes together so I get a linked list, however, when I check the linked list it says the list is empty, not sure where the problem is but i assume it's something with the nodes not being linked together correctly
this is the code
#include <stdio.h>
#include <stdlib.h>
#include <intrin.h>
#include <string.h>
void Load_bus_information();
void Load_pass_information();
int Assign_passengers_print_buss_information();
int Print_specific_bus_info();
int Print_unmatched_passengers();
int Add_new_passenger();
void Delete_passenger();
int Delete_bus_number();
char source_all[150][150];
char destination_all[150][150];
int id_all [150];
char time_all[250][250];
int date_all [150];
///////////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
int bus_number[150];
int bus_date[150];
char bus_time[155][150];
char sourceBus_all[150][150];
char destinationBus_all[150][150];
int capacity[150];
int price[150];
///////////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
struct passenger
{
int id_p ;
int date_p ;
char time_p[150] ;
char sour_p[150];
char des_p[150];
struct passenger* Next;
};
struct bus
{
int num ;
int date_b;
char time_b ;
char des_b;
char sour_p;
struct bus* Next;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void insert(int id2,int date2,char time2[], char sou2[], char dest2[], struct passenger* L );
struct passenger* FindPrevious(int X, struct passenger* L);
struct passenger* IsLast(struct passenger* P, struct passenger* L);
int isEmpty(struct passenger* L);
void Delete(int X, struct passenger* L);
struct passenger *start=NULL;
struct passenger* L;
void PrintList( struct passenger *L);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
int task=0;
do
{
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf("1. Load the bus information file. \n");
printf("2. Load the passenger information file. \n");
printf("3. Assign passengers and print assignment information of all busses.\n");
printf("4. Print a specific bus information along with its passengers information (names and IDs).\n");
printf("5. Print unmatched passengers. \n");
printf("6. Add new passenger.\n");
printf("7. Delete passenger.\n");
printf("8. Delete bus number.\n");
printf("9. Exit.\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
scanf("%d",&task);
switch(task)
{
case 1:
Load_bus_information();
break;
case 2:
Load_pass_information();
break;
case 3:
Assign_passengers_print_buss_information();
break;
case 4:
Print_specific_bus_info();
break;
case 5:
Print_unmatched_passengers();
break;
case 6:
Add_new_passenger();
break;
case 7:
Delete_passenger();
break;
case 8:
Delete_bus_number();
break;
default:
exit(-1);
//}
}
}
while (task!=9);
return 0;
}
//********************************
void insert(int id2,int date2,char time2[], char sou2[], char dest2[], struct passenger* L )
{
struct passenger *temp2 = NULL, *current = NULL, *head = NULL;
// L = head ;
temp2 = (struct passenger*)malloc(sizeof(struct passenger));
// head = NULL; head = (struct passenger*)malloc(sizeof(struct passenger));
temp2->Next=NULL;
temp2->id_p = id2;
temp2->date_p= date2;
strcpy(temp2->time_p, time2);
strcpy(temp2->sour_p, sou2);
strcpy(temp2->des_p, dest2);
temp2->Next = NULL;
// temp2->Next = head->Next;
//head->Next= temp2;
if(head ==NULL)
{
head = temp2;
current = temp2;
}
else
{
current->Next = temp2 ;
current = current->Next ;
}
printf(" %-10d %-10d %-10s %-10s %-10s \n",temp2->id_p, temp2->date_p, temp2->time_p,temp2->sour_p,temp2->des_p);
head = L ;
}
/*
void insert(int id2,int date2,char time2[], char sou2[], char dest2[] , struct passenger **head)
{
//create a new node
struct passenger *temp2 = malloc(sizeof(struct passenger));
temp2->id_p = id2;
temp2->date_p= date2;
strcpy(temp2->time_p, time2);
strcpy(temp2->sour_p, sou2);
strcpy(temp2->des_p, dest2);
temp2->Next= NULL;
if(*head == NULL)
*head = temp2;
printf(" %d %d %s %s %s \n",temp2->id_p, temp2->date_p, temp2->time_p,temp2->sour_p,temp2->des_p);
//if head is NULL, it is an empty list
}*/
struct passenger* FindPrevious(int X, struct passenger* L)
{
struct passenger* P;
struct passenger* S = L -> Next;
P = L;
while(P->Next != NULL && P->Next->id_p != X)
P = P->Next;
S = S->Next;
return P;
}
struct passenger* IsLast(struct passenger* P, struct passenger* L)
{
return P->Next == NULL ;
}
int isEmpty(struct passenger* L)
{
return L->Next ==NULL;
}
void Delete(int X, struct passenger* L)
{
if(!isEmpty(L))
{
struct passenger* P;
struct passenger* temp;
P = FindPrevious(X, L);
if(P!= NULL)
{
temp = P->Next;
P->Next = temp->Next; //bypass delete cell
free(temp);
}
}
}
struct passenger* MakeEmpty(struct passenger* L)
{
L = ( struct passenger *)malloc(sizeof(struct passenger));
if(L == NULL)
printf ("Out of memory!\n");
else
L->Next = NULL;
return L;
}
void Load_bus_information()
{
FILE* file;
char chB;
char Bname[20];
// Opening file in reading mode
file = fopen("busses.txt", "r");
if (NULL == file)
{
("file can't be opened \n");
}
char Bbuf[100] ;
char Btemp[150];
char timeB[145] ;
char Bdestination[150] ;
char Bsource[150] ;
int bus_num, dateB, cap, pr ;
int counter =0;
while (fgets(Bbuf,100,file))
{
bus_num = atoi( strcpy(Btemp,strtok(Bbuf,"#")));
dateB= atoi( strcpy(Btemp,strtok(NULL,"#")));
strcpy(timeB,strtok(NULL,"#"));
strcpy(Bsource,strtok(NULL,"#"));
strcpy(Bdestination,strtok(NULL,"#"));
pr= atoi( strcpy(Btemp,strtok(NULL,"#")));
cap= atoi( strcpy(Btemp,strtok(NULL,"#")));
for(int s=0; s<5; s++)
{
price[s]= pr;
}
for(int s=0; s<5; s++)
{
capacity[s]= cap;
}
for(int s=0; s<5; s++)
{
bus_number[s]= bus_num;
}
for(int s=0; s<150; s++)
{
bus_date[s]= dateB;
}
for(int s=0; s<150; s++)
{
bus_time[counter][s]= timeB[s];
}
for(int s=0; s<150; s++)
{
sourceBus_all[counter][s]= Bsource[s];
}
for(int s=0; s<150; s++)
{
destinationBus_all[counter][s]= Bdestination[s];
}
counter++;
printf("%-10d %-10d %-10s %-15s %-15s %-15d %-15d \n",bus_num, dateB, timeB, Bsource, Bdestination, pr, cap );
}
}
void Load_pass_information()
{
FILE* fout;
char ch;
char fname[20];
// Opening file in reading mode
fout = fopen("passengers.txt", "r");
if (NULL == fout)
{
printf("file can't be opened \n");
}
// Printing what is written in file
char buf[100] ;
char temp[150];
char source[150] ;
char destination[150] ;
char time[150] ;
int date ;
int id ;
int count =0;
// cutting each line in the file and store them in variables
while (fgets(buf,100,fout))
{
id = atoi( strcpy(temp,strtok(buf,"#")));
date= atoi( strcpy(temp,strtok(NULL,"#")));
strcpy(time,strtok(NULL,"#"));
strcpy(source,strtok(NULL,"#"));
strcpy(destination,strtok(NULL,"#"));
//****************
struct passenger * head;
insert(id, date, time, source, destination, L );
}
count++;
fclose(fout);
}
int Assign_passengers_print_buss_information()
{
//passenger * buss_array[100];
}
int Print_specific_bus_info()
{
}
int Print_unmatched_passengers()
{
}
int Add_new_passenger()
{
int add_id, add_date;
char add_time[100],add_source [100], add_destination [100];
printf("please enter the id of the passenger:_");
scanf("%d", &add_id);
printf("please enter the date :_");
scanf("%d", &add_date);
printf("please enter the time:_");
// for (int i = 0;i < 4;i++)
scanf("%s", add_time);
printf("please enter the place to be collected :_");
scanf("%s", add_source);
printf("please enter the destination:_");
scanf("%s", add_destination);
printf("\n");
Load_pass_information();
insert(add_id, add_date, add_time, add_source, add_destination, L );
//Load_pass_information();
printf("\n");
}
void Delete_passenger( )
{
int X;
printf("enter id of the passenger that will be deleted ");
scanf("%d", &X);
Delete( X,L);
Load_pass_information();
}
int Delete_bus_number()
{
struct passenger*L;
PrintList(L);
}
void PrintList( struct passenger *L)
{
struct passenger* P = L;
if( isEmpty(L))
printf("Empty list\n");
else
do
{
P=P->Next;
printf(" %-10d %-10d %-10s %-10s %-10s \n",P->id_p, P->date_p, P->time_p,P->sour_p,P->des_p);
}
while( !IsLast(P, L) );
printf("\n");
}
this is the whole code so you can copy&paste it if you want, now if you press 8 it should not delete, I made it so it tells if the list is empty or not, which in my case it tells me the list is empty when it shouldn't be.
now load_pass is the function that's responsible to read from the file (read a line and pars it) the insert function should take care of the nodes
the data that would be included in the file:
1970111231#12:51#12072015#London#Liverpool
1251222415#01:12#16012015#California#Florida
1255122451#00:15#12052019#Chicago#Arizona
just to clarify when pressing 8 it should print the parsed data, i.e: 1970111231 12:51 12072015 London Liverpool

C- Linked List with *chars

I am trying to build a simple linked list.
I have successfully built a linked list only with int variables but when I add *char variables the output is wrong.
The int values seem to be correct but the *char type are wrong.
The *char type seem to always be the last one inserted.
Sample Input
Number: 5
Character: a
Number: 4
Character: b
Sample Output
5
b
**************
4
b
#include <stdio.h>
#include <stdlib.h>
typedef struct BOOKS
{
int value;
char *char_value;
struct BOOKS *next;
} BOOKS;
BOOKS *insert_value(BOOKS *node, int n, char *char_value);
BOOKS *read_list(BOOKS *head);
int main()
{
int aux = 0;
int menu = 0;
int option;
BOOKS *head = NULL;
BOOKS *tail = NULL;
while (menu != -2)
{
int choices;
printf("1. Insert Book\n");
printf("2. Print Books\n");
printf("3. Exit\n");
scanf("%d", &choices);
switch (choices)
{
case 1:
{
int n;
char char_value[2000] = "";
printf("Number:");
scanf("%d", &n);
printf("Character: ");
scanf("%s", &char_value);
if (aux == 0)
{
/*FIRST INTERACTION*/
head = malloc(sizeof(BOOKS));
tail = malloc(sizeof(BOOKS));
head = tail = insert_value(tail, n, char_value);
aux = 1;
}
else
{
tail->next = malloc(sizeof(BOOKS));
/*FORMING TAIL->NEXT*/
tail->next = insert_value(tail->next, n, char_value);
/*ASSIGNING TAIL->NEXT AS THE NEW TAIL */
tail = tail->next;
}
break;
}
case 2:
{ /*READ THE LIST*/
read_list(head);
break;
}
case 3:
{
menu = -2;
break;
}
default:
printf("Invalid choice\n");
break;
}
}
}
BOOKS *insert_value(BOOKS *node, int n, char *char_value)
{
node->value = n;
node->char_value = char_value;
node->next = NULL;
return node;
}
BOOKS *read_list(BOOKS *head)
{
BOOKS *a = head;
while (a != NULL)
{
printf("%d\n", a->value);
printf("%s\n", a->char_value);
printf("\n********************\n");
a = a->next;
}
}
You're passing char_value from main to your insert_books function, and then saving this pointer in your newly created node. The address of char_value from main doesn't change, so you're saving the same address to each node you create. Since all these pointers point to the same place, they will all read back whatever value was written there last. If you want to make a copy of string in each node, you can use (non standard) strdup or malloc more memory and use strcpy. But, it's an odd design choice you're using a character array to accept one character anyway. I recommend changing char_value in both main and struct BOOKS to char char_value;, then you can simply use equals assignment as with value to save copies of the char. Be sure to scanf a char the correct way.
A couple of other things:
As written, you can change scanf("%s", &char_value); to scanf("%s", char_value);. char_value is a character array, which decays to a char* in this context, there's no need to specify the address of char_value.
head = malloc(sizeof(BOOKS));
tail = malloc(sizeof(BOOKS));
head = tail = insert_value(tail, n, char_value);
This is a memory leak. You're allocating separate memory for head and tail, but then setting both pointers equal to the memory allocated for tail (the return value of insert_value). The memory allocated for head is never freed nor used.
This will help with the errors:-
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
typedef struct BOOKS
{
int value;
char char_value[2000];
struct BOOKS *next;
} BOOKS;
BOOKS *insert_value(BOOKS *node, int n, char *char_value);
BOOKS *read_list(BOOKS *head);
int main()
{
int aux = 0;
int menu = 0;
int option;
BOOKS *head = NULL;
BOOKS *tail = NULL;
while (menu != -2)
{
int choices;
printf("1. Insert Book\n");
printf("2. Print Books\n");
printf("3. Exit\n");
scanf("%d", &choices);
switch (choices)
{
case 1:
{
int n;
char char_value[2000];
printf("Number:");
scanf("%d", &n);
printf("Character: ");
scanf("%s", char_value);
if (aux == 0)
{
/*FIRST INTERACTION*/
head = malloc(sizeof(BOOKS));
tail = malloc(sizeof(BOOKS));
head = tail = insert_value(tail, n, char_value);
aux = 1;
}
else
{
tail->next = malloc(sizeof(BOOKS));
/*FORMING TAIL->NEXT*/
tail->next = insert_value(tail->next, n, char_value);
/*ASSIGNING TAIL->NEXT AS THE NEW TAIL */
tail = tail->next;
}
break;
}
case 2:
{ /*READ THE LIST*/
read_list(head);
break;
}
case 3:
{
menu = -2;
break;
}
default:
printf("Invalid choice\n");
break;
}
}
}
BOOKS *insert_value(BOOKS *node, int n, char *char_value)
{
node->value = n;
int size = sizeof(char_value)/sizeof(char);
strncpy(node->char_value, char_value, size);
node->next = NULL;
return node;
}
BOOKS *read_list(BOOKS *head)
{
BOOKS *a = head;
while (a != NULL)
{
printf("%d\n", a->value);
printf("%s\n", a->char_value);
printf("\n********************\n");
a = a->next;
}
}

Data are not stacking in the queue

I have made a queue of nodes to store the data.
And the data should be implemented through file I/O.
In .txt file:
"Name1"
"Birthday1 (month date)"
"Genre1"
"Name2"
"Birthday2 (month date)"
"Genre2"
(above form is repeated)
Whenever I try to run through the code, it shows some strange characters for Name, Genre, and Birthday.
Also, same lines are repeated for 14 times.
I guess the problem has to do with data_in function.
What is the problem, and how can I fix it?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable:4996)
typedef struct node {
char *name, *genre;
int month, date;
struct Node *next;
}Node;
typedef struct Queue {
Node *front;
Node *rear;
int count;
}Queue;
void queue_init(Queue *queue) {
//Initializing needed in order to use the queue
queue->front = queue->rear = NULL;
queue->count = 0;
}
int isEmpty(Queue *queue) {
//Check whehter the queue is empty or not
return (queue->count == 0);
}
void display_node(Node *node) {
printf("\nName: %s", node->name);
printf("\nFavorite Genre: %s", node->genre);
printf("\nBirthday: %d / %d", node->month, node->date);
printf("\n");
}
void data_in(Queue *queue) {
Node *now = (Node *)malloc(sizeof(Node));
FILE *f;
f = fopen("C:\\Users\\brain\\Desktop\\School\\2-2 GWU\\Data Structures and Algorithm\\LAB\\Lab Assignment\\Lab Assignment 3.txt", "r");
for(int i = 0; i < 14; i++) {
char n[100], g[100];
fscanf(f, "%s", &n);
fscanf(f, "%d %d", &now->month, &now->date);
fscanf(f, "%s", &g);
fgets(f);
now->name = (char *)malloc(sizeof(char)*strlen(n));
now->genre = (char *)malloc(sizeof(char)*strlen(g));
now->name = n;
now->genre = g;
if (isEmpty(queue))
queue->front = now;
else
queue->rear->next = now;
queue->rear = now;
queue->count++;
}
fclose(f);
}
void search(Queue *queue) {
Node *now = queue->front;
char c[100], check[100];
int ch, cnt = 0;
printf("Which section do you want to search? (Genre or Month): ");
scanf("%s", &c);
if (strcmp(c, "Genre") == 0) {
printf("Type the genre: ");
scanf("%s", &check);
for (int i = 0; i < queue->count; i++) {
if (now != NULL) {
if (strcmp(now->genre, check)) {
display_node(now);
now = now->next;
cnt = 1;
}
}
}
if (cnt == 0) printf("\n.....No results found...");
}
else if (strcmp(c, "Month") == 0) {
printf("Type month as an integer: ");
scanf("%d", &ch);
for (int j = 0; j < queue->count; j++) {
if (now != NULL) {
if (now->month == ch) {
display_node(now);
now = now->next;
cnt = 1;
}
}
}
if (cnt == 0) printf("\n.....No results found...");
}
}
int main(void) {
int check = 1;
Queue DSA;
queue_init(&DSA);
data_in(&DSA);
while (check == 1) {
search(&DSA);
printf("\nDo you want to continue searching? (1 or 0): ");
scanf("%d", &check);
printf("\n============================================================\n");
}
system("pause");
return 0;
}```
These two lines are definitely NOT what you want:
fscanf(f, "%s", &n);
fscanf(f, "%s", &g);
they should read:
fscanf(f, "%s", n);
fscanf(f, "%s", g);
(notice the removed &).
Also, the next line:
fscanf(f, "%d %d", &now->month, &now->date);
should have a space as the first character of the format string:
fscanf(f, " %d %d", &now->month, &now->date);

Adding struct pointer to a pointer array

I have a problem and I really dont know what to do.
I'am trying to insert "new students" to an student-array. The array contains pointers to the created structs. Can somebody find the error? It adds the student-structs to the array but especially the printing doesnt work.
It would be really helpful, if somebody could help me. :) PS: You can just copy the code.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_HASH 10
typedef struct student
{
unsigned int matnr;
char *name;
struct student *next_student;
} Student;
Student **hash_tabelle[MAX_HASH];
void insert_student (unsigned int matnr, char *name)
{
Student *neuer_student = malloc(sizeof(Student));
neuer_student->name = malloc(sizeof(*name)+1);
neuer_student->matnr = matnr;
strcpy(neuer_student->name, name);
neuer_student->next_student = NULL;
// Index im Hash-Array ermitteln
int hash_index = matnr % 10;
if(hash_tabelle[hash_index] == NULL)
{
neuer_student->next_student = hash_tabelle[hash_index];
hash_tabelle[hash_index] = neuer_student;
}
else
{
while(*hash_tabelle[hash_index] != NULL && (((*hash_tabelle[hash_index])->matnr - neuer_student->matnr) <= 0))
hash_tabelle[hash_index] = &(*hash_tabelle[hash_index])->next_student;
neuer_student->next_student = *hash_tabelle[hash_index];
*hash_tabelle[hash_index] = neuer_student;
}
}
void print_hash_tabelle()
{
for(int i = 0; i != MAX_HASH - 1; i++){
printf("%d)\t", i);
hash_tabelle[i] = &(*hash_tabelle[i])->next_student;
for(; hash_tabelle[i] != NULL; hash_tabelle[i] = &(*hash_tabelle[i])->next_student){
printf("%s (%d)", (&(*hash_tabelle[i])->name), (&(*hash_tabelle[i])->matnr));
}
printf("\t");
}
}
int main()
{
unsigned int matnr;
char name[100];
do
{
printf("Matrikelnummer:\t");
scanf("%d", &matnr);
fflush(stdin);
getchar(); // um das \n aus dem Puffer zu kriegen und rauszuschmeißen
printf("Name:\t\t");
fgets(name, 30, stdin);
insert_student(matnr, name);
}
while (matnr != 0);
print_hash_tabelle();
return 0;
}
Using a hash table is so simple... No need to use dereferencing for a fixed-size array of linked-list pointers.
Step 1 - a hash table is a array of linked-list pointers.
As #BLUEPIXY suggests:
Student *hash_tabelle[MAX_HASH];
Step 2 - to allocate and free each linked-list, initialize each item to NULL.
Otherwise, if(hash_tabelle[hash_index] == NULL) is Undefined
behavior in the function insert_student().
void hash_init()
{
for(int i=0;i<MAX_HASH;i++) {
hash_tabelle[MAX_HASH]=NULL;
}
}
Step 3 - allocate enough char to store the char *name to insert_student().
As # WhozCraig suggests, use strlen().
void insert_student (unsigned int matnr, char *name)
{
Student *neuer_student = malloc(sizeof(Student));
neuer_student->name = malloc(strlen(name)+1);
neuer_student->matnr = matnr;
strcpy(neuer_student->name, name);
neuer_student->next_student = NULL;
Step 4 - add the neuer_student in the hash_tabelle[] (function insert_student())
Warning: the index shall be included in the size of the array
[0..MAX_HASH[. (using 10 instead of MAX_HASH could become a bug).
int hash_index = matnr % MAX_HASH;
When the hash_tabelle[hash_index] is NULL, simple store the
neuer_student. No need to modify neuer_student->next_student.
if(hash_tabelle[hash_index] == NULL)
{
hash_tabelle[hash_index] = neuer_student;
}
Else explore the linked-list of hash_tabelle[hash_index] to store
the neuer_student at the end.
else
{
Student *tmp;
tmp = hash_tabelle[hash_index];
while (tmp->next_student!=NULL) {
tmp = tmp->next_student;
}
tmp->next_student = neuer_student;
}
Step 5 - to print the all items of the hash table (function print_hash_tabelle())
Reuse the same method to explore each linked-list pointer.
Warning: explore all item from 0 to MAX_HASH-1
void print_hash_tabelle()
{
for(int i = 0; i < MAX_HASH; i++){ // ERR != MAX_HASH - 1; i++){
printf("%d)\t", i);
Student *tmp = hash_tabelle[i];
while (tmp!=NULL) {
printf("%s (%d)", tmp->name, tmp->matnr);
tmp = tmp->next_student;
}
printf("\n");
}
}
Step 6 - free the memory of each item of the hash_tabelle[].
Free the allocated string free(tmp->name);.
Remove the current student hash_tabelle[i] = tmp->next_student;
Free the allocated student free(tmp);
Repeat until the end of the linked-list
That's all (no change in the main() except adding a call to hash_free() at the end).
void hash_free()
{
for(int i=0;i<MAX_HASH;i++) {
Student *tmp = hash_tabelle[i];
while (tmp!=NULL) {
free(tmp->name);
hash_tabelle[i] = tmp->next_student;
free(tmp);
tmp = hash_tabelle[i];
}
}
}
like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_HASH 10
typedef struct student {
unsigned int matnr;
char *name;
struct student *next_student;
} Student;
Student *hash_tabelle[MAX_HASH];
void insert_student (unsigned int matnr, char *name){
Student *neuer_student = malloc(sizeof(Student));
neuer_student->name = malloc(strlen(name)+1);
strcpy(neuer_student->name, name);
neuer_student->matnr = matnr;
//neuer_student->next_student = NULL;
int hash_index = matnr % MAX_HASH;
Student head = { .next_student = hash_tabelle[hash_index] };
Student *prev = &head, *curr = head.next_student;
while(curr != NULL && curr->matnr <= neuer_student->matnr){
prev = curr;
curr = curr->next_student;
}
neuer_student->next_student = curr;
prev->next_student = neuer_student;
hash_tabelle[hash_index] = head.next_student;
}
void print_hash_tabelle(void){
for(int i = 0; i < MAX_HASH; i++){
printf("%d)\t", i);
for(Student *p = hash_tabelle[i]; p; p = p->next_student){
printf("%s (%d)\t", p->name, p->matnr);
}
printf("\n");
}
}
void free_hash_tabelle(void){
for(int i = 0; i < MAX_HASH; i++){
Student *p = hash_tabelle[i];
while(p){
Student *temp = p->next_student;
free(p->name);
free(p);
p = temp;
}
}
}
int main(void){
int matnr = -1;//for %d of scanf
char name[100];
while(1){
printf("Matrikelnummer(-1 for end input): ");fflush(stdout);
scanf("%d", &matnr);
if(matnr < 0)
break;
while(getchar() != '\n');
printf("Name: ");fflush(stdout);
fgets(name, sizeof name, stdin);
name[strcspn(name, "\n")] = 0;
insert_student(matnr, name);
}
print_hash_tabelle();
free_hash_tabelle();
return 0;
}

I m trying to sort the node by score. I do not know what error i am having

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
struct student{
char firstname[20];
char lastname[20];
double grade;
char zipcode[10];
struct student *next;
};
void display(struct student *first)
{
while (first != NULL)
{
printf("\nFirst name: %s", first->firstname);
printf("\tLast name: %s", first->lastname);
printf("\tGrade: %.2f", first->grade);
printf("\t ZipCode: %s", first->zipcode);
first = first->next;
}
}
/*void add_Record(struct student *first)
{
char r[20];
struct student *t;
t = first;
while (t != NULL)
{
if (t == NULL)
{
first = (struct student*)malloc(sizeof(struct student));
printf("\nEnter the first name of the student:");
scanf("%s", first->firstname);
printf("\nEnter the last name of the student:");
scanf("%s", first->lastname);
printf("\nEnter the score of the student:");
scanf("%lf", &first->grade);
printf("\nEnter the zipcode of the student:");
scanf("%s", first->zipcode);
}
}
}
void del()
{
struct student *back, *t, *k;
char r[10];
int flag = 0;
printf("\nEnter the last name of student you want to delete:");
scanf("%s", r);
if (strcmpi(r, first->lastname) == 0)
{
first = first->next;
flag = 1;
}
else
{
back = first;
k = first->next;
while (k != NULL)
{
if (strcmpi(r, k->lastname) == 0)
{
back->next = k->next;
flag = 1;
break;
}
}
}
if (flag == 0)
printf("\nThe element not found!!!");
}
*/
void search(struct student *first)
{
char r[10];
int flag = 0;
printf("\nEnter the zipcode you want to search:");
scanf("%s", r);
struct student *t;
t = first;
while (t != NULL)
{
if (strcmp(r, t->zipcode) == 0)
{
printf("\nFirst name: %s", t->firstname);
printf("\tLast name: %s", t->lastname);
printf("\tGrade: %.2f", t->grade);
printf("\t ZipCode: %s", t->zipcode);
flag = 1;
break;
}t = t->next;
}
if (flag == 0)
printf("\nThe zipcode not in database!!");
}
void sort(struct student *first)
{
struct student *temp;
temp = NULL;
while (first != NULL)
{
if (first-> grade > first->next->grade)
{
strcpy(temp->firstname, first->firstname);
strcpy(temp->lastname, first->lastname);
temp->grade = first->grade;
strcpy(temp->zipcode, first->zipcode);
strcpy(first->firstname, first->next->firstname);
strcpy(first->lastname, first->next->lastname);
first->grade = first->next->grade;
strcpy(first->zipcode, first->next->zipcode);
strcpy(first->next->firstname, temp->firstname);
strcpy(first->next->lastname, temp->lastname);
first->next->grade = temp->grade;
strcpy(first->next->zipcode, temp->zipcode);
break;
}
}
printf("\nThe sorted record by score are: \n");
display(first);
}
int main(void)
{
struct student *first = NULL, *last = NULL;
struct student *temp;
int n;
printf("\nEnter the number of student:");
scanf("%d", &n);
int i;
for (i = 0; i < n; i++)
{
temp = (struct student*)malloc(sizeof(struct student));
printf("\nEnter the first name of the student:");
scanf("%s", temp->firstname);
printf("\nEnter the last name of the student:");
scanf("%s", temp->lastname);
printf("\nEnter the grade of the student:");
scanf("%lf", &temp->grade);
printf("\nEnter the zipcode of the student:");
scanf("%s", temp->zipcode);
temp->next = first;
first = temp;
}
int o;
o = 1;
while (o != 0)
{
printf("\nMENU\n");
printf("\nEnter 1 for displaying database.");
printf("\nEnter 2 for inserting an record.");
printf("\nEnter 3 for deleting a record by lastname.");
printf("\nEnter 4 for searching a record by zipcode.");
printf("\nEnter 5 for sorting record by score.");
printf("\nEnter 0 for exit!");
printf("\nEnter the choice:");
scanf("%d", &o);
switch (o)
{
case 1:display(first); break;
/*case 2:insertafter(*first); break;
case 3:del(); break;*/
case 4:search(first); break;
case 5: sort(first); break;
case 0:exit(0); break;
default:printf("\nYou have entered a wrong choice!!!");
}
}
}
The problem is that how do i sort the scores by score. My code seems right but doesn't work. I made a temp structure and tried to swap values but it doesn't work. Am i doing the loop wrong? Or all my code is wrong?
Here are two answers to the problem
First one sorts the nodes in the node linked list by bubble sorting them, rearranging the linked list
Second one walks the linked list, copies a pointer to each one into an array and then sorts the array by using the struct grade members, the linked list remains unchanged
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define SWAP(T,x,y) {T *p = &(x); T *q = &(y); T z = *p; *p = *q; *q = z;}
struct student{
char firstname[20];
char lastname[20];
double grade;
char zipcode[10];
struct student *next;
};
struct student *head=NULL;
void add(char *f, char *s, double score) {
struct student *a;
a=(struct student*)malloc(sizeof(struct student));
strcpy(a->firstname,f);
strcpy(a->lastname,s);
a->grade = score;
a->next = head;
head = a;
}
void printout(char *label) {
struct student *node;
printf("%s\n",label);
for(node=head; node !=NULL; node=node->next) {
printf("%s %s %f\n", node->firstname, node->lastname, node->grade);
}
}
int main(int argc, char ** argv){
int mark=8;
struct student *walk, *prev;
add("Bob","Smith",10);
add("Eric","Von Däniken",90);
add("Morris","Minor",91);
add("Master","Bates",9);
add("Zoe","Bodkin",20);
add("Mary","Pippin",30);
/* bubble sort */
printout("before");
prev=head;
while(mark) {
mark=0;
for(walk=head;
walk != NULL;
walk=walk->next) {
if (walk->next && walk->grade > walk->next->grade) {
/* printf("swapping %s %s\n", walk->firstname, walk->next->firstname); */
mark=1;
if (walk == head) {
struct student *v2=walk->next;
struct student *v3=walk->next->next;
SWAP(struct student *, v3->next, v2->next);
SWAP(struct student *, head, v3->next);
walk = v3;
} else {
struct student *v1=prev;
struct student *v2=walk;
struct student *v3=walk->next;
SWAP(struct student *, v3->next, v2->next);
SWAP(struct student *, v1->next, v3->next);
walk = v3;
}
}
prev=walk;
}
}
printout("after");
return 0;
}
second version, uses qsort, retains linked list order
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
struct student{
char firstname[20];
char lastname[20];
double grade;
char zipcode[10];
struct student *next;
};
struct student *head=NULL;
size_t nodecount=0;
void add(char *f, char *s, double score) {
struct student *a;
a=(struct student*)malloc(sizeof(struct student));
strcpy(a->firstname,f);
strcpy(a->lastname,s);
a->grade = score;
a->next = head;
head = a;
nodecount++;
}
static int cmpgrade(const void *p1, const void *p2) {
struct student *g1, *g2;
g1=*(struct student **)p1;
g2=*(struct student **)p2;
return g1->grade > g2->grade;
}
int main(int argc, char ** argv){
int i;
struct student *walk,**sa, **sap;
add("Bob","Smith",10);
add("Eric","Von Däniken",90);
add("Morris","Minor",91);
add("Master","Bates",9);
add("Zoe","Bodkin",20);
add("Mary","Pippin",30);
/*copy into array of pointers*/
sa=calloc(sizeof (struct student*), nodecount);
sap=sa;
for(walk=head; walk != NULL; walk=walk->next) {
*sap = walk;
sap++;
}
printf("before\n");
for (i=0; i< nodecount; i++) {
printf("%s %s %f\n", sa[i]->firstname, sa[i]->lastname, sa[i]->grade);
}
/* qsort */
qsort(sa, nodecount, sizeof (struct student *), cmpgrade);
printf("after\n");
for (i=0; i< nodecount; i++) {
printf("%s %s %f\n", sa[i]->firstname, sa[i]->lastname, sa[i]->grade);
}
return 0;
}

Resources