Adding a string in a node - c

i have a problem with adding an string type inside of a node list.
I am using the command strncpy(), but i am not sure how this works with the pointer.
This is the code block i have now.
My specific problem is in the function "Insertar" because it expects a type char *variable but i an inserting just a char.
#ifndef _LINK_LIST_H_
#define _LINK_LIST_H_
#include <stdio.h>
typedef struct
{
int dia;
int mes;
int ano;
}fecha;
struct NODEL
{
float valor;
char variable [10];
int resol;
fecha f;
struct NODEL* nextNode;
};
typedef struct NODEL LISTNODE;
typedef LISTNODE * LISTNODEPTR;
void insertar(LISTNODEPTR * lista, float newvalor, char *variable, int newresol,
#endif
void insertar(LISTNODEPTR * lista, float newvalor, char *variable, int newresol, int newdia, int newmes, int newano)
{
LISTNODEPTR newPtr, prevPtr, currPtr;
newPtr = malloc(sizeof(LISTNODE));
if(newPtr != NULL)
{
newPtr->valor = newvalor;
strncpy(newPtr->variable,newPtr->variable,10);
newPtr->resol = newresol;
newPtr->f.dia = newdia;
newPtr->f.mes = newmes;
newPtr->f.ano = newano;
newPtr->nextNode = NULL;
prevPtr = NULL;
currPtr = *lista;
while(currPtr != NULL && newvalor > currPtr->valor)
{
prevPtr = currPtr;
currPtr = currPtr->nextNode;
}
if(prevPtr == NULL)
{
newPtr->nextNode = *lista;
*lista = newPtr;
}
else
{
prevPtr->nextNode = newPtr;
newPtr->nextNode = currPtr;
}
}
else
{
printf("Elemento no insertado, no hay memoria disponible\n");
}
}
int main(void)
{
LISTNODEPTR data_base;
float valorADC;
char varIngresada;
int resolucion;
int diaIng;
int mesIng;
int anoIng;
printf("Valor de ADC: ");
scanf("%f", &valorADC);
fflush(stdin);
printf("Tipo variable 'Presion'/'Temperatura'/'Aceleracion': ");
scanf("%s", &varIngresada);
fflush(stdin);
printf("Resolución: ");
scanf("%d", &resolucion);
fflush(stdin);
printf("Fecha (dia): ");
scanf("%d", &diaIng);
fflush(stdin);
printf("Fecha (mes): ");
scanf("%d", &mesIng);
fflush(stdin);
printf("Fecha (año): ");
scanf("%d", &anoIng);
fflush(stdin);
insertar(&data_base, valorADC, varIngresada, resolucion, diaIng, mesIng, anoIng);
imprimir(data_base);
}

Related

Segmentation fault error in Linked-List program

I'm facing the segmentation fault error in the following dynamic linked list implementation; GDB shows the issue is on the node = node->next line in the "l_print" function of the linked-list ("LIST_CL.H" file). Anyone can help? I even tried "drawing debug" on paper but still I'm not getting the issue here.
Note: I report the whole code for both the insert and the print, in case it's useful. Therefore LIST.C file include the "switch case 6" to insert the element ("l_add" function in "LIST_CL.H" file) and the "switch case 1" to print the list ("l_print" function in "LIST_CL.H" file)
Note: The issue only happen when the list has one or more items. There's no errors when the list is empty ("list_cl" struct has NULL for both head and tail nodes)
LIST.C:
#include <stdio.h>
#include <string.h> //for strcpy
#include "cl_list.h"
#include "list_cl.h"
#define STRING_SIZE 25
int main(){
list_cl class = L_EMPTYLIST_CL;
puts("Select command:");
puts("0. Exit.");
puts("1. Insert node.");
puts("6. Print all nodes in the linked list.");
int k = 0;
scanf("%d", &k);
while(k != 0){
switch(k){
case 1:
char cf[17] = "";
char first_name[STRING_SIZE] = "";
char last_name[STRING_SIZE] = "";
getchar();
puts("Insert name:");
fgets(first_name, sizeof(first_name), stdin);
puts("Insert surname:");
fgets(last_name, sizeof(last_name), stdin);
puts("Insert fiscal code:");
fgets(cf, sizeof(cf), stdin);
client cliente;
strcpy(cliente.cf, cf);
cliente.first_name = first_name;
cliente.last_name = last_name;
class = l_add_cl(class, cliente);
puts("Node inserted.");
break;
case 6:
l_print(class);
break;
default:
break;
}
scanf("%d", &k);
}
}
LIST_CL.H:
list_cl l_add_cl(list_cl l, client p){
l_node node;
node.id = 1;
node.person = p;
node.next = NULL;
if(l.head == NULL){
//List is empty
l.head = &node;
l.tail = &node;
} else {
l.tail -> next = &node;
l.tail = &node;
}
return l;
}
void l_print(list_cl l){
l_node *node = NULL;
node = l.head;
while(node != NULL){
//client *cliente = &node->person;
//printf("ID Elemento: %d | Name: %s Surname: %s Fiscal Code: %s", node->id, cliente->first_name, cliente->last_name, cliente->cf);
node = node->next; // SEGMENTATION FAULT ERROR HERE!
}
}
CL_LIST.H:
#include "client.h"
typedef struct _node {
unsigned int id;
client person;
struct _node *next;
} l_node;
typedef struct {
l_node *head;
l_node *tail;
} list_cl;
#define L_EMPTYLIST_CL {NULL,NULL}
CLIENT.H:
typedef struct {
char cf[17];
char *first_name;
char *last_name;
} client;
Fixed code:
LIST.C:
#include <stdio.h>
#include <string.h> //for strcpy
#include "cl_list.h"
#include "list_cl.h"
#define STRING_SIZE 25
int main(){
list_cl class = L_EMPTYLIST_CL;
puts("Seleziona un comando:");
puts("0. Exit.");
puts("1. Insert one node.");
puts("6. Print all nodes.");
int k = 0;
scanf("%d", &k);
while(k != 0){
switch(k){
case 1:
char cf[17] = "";
//char first_name[STRING_SIZE] = ""; THIS CAUSE DATA INCONSISTENCY
//char last_name[STRING_SIZE] = ""; THIS CAUSE DATA INCONSISTENCY
char *first_name = malloc(sizeof(char)*STRING_SIZE);
char *last_name = malloc(sizeof(char)*STRING_SIZE);
getchar();
puts("Insert name:");
//fgets(first_name, sizeof(first_name), stdin); ISSUE WITH SIZE OF FIRST_NAME
fgets(first_name, sizeof(char)*STRING_SIZE, stdin);
puts("Insert surname:");
//fgets(last_name, sizeof(last_name), stdin); ISSUE WITH SIZE OF LAST_NAME
fgets(last_name, sizeof(char)*STRING_SIZE, stdin);
puts("IInsert fiscal code:");
fgets(cf, sizeof(cf), stdin);
client *cliente = malloc(sizeof(client));
strcpy(cliente->cf, cf);
cliente->first_name = first_name;
cliente->last_name = last_name;
class = l_add_cl(class, *cliente);
puts("Element inserted.");
break;
case 6:
l_print(class);
break;
default:
break;
}
puts("Select command:");
scanf("%d", &k);
}
}
LIST_CL.H
list_cl l_add_cl(list_cl l, client p){
l_node *node = malloc(sizeof(struct _node));
node->id = 1;
node->person = p;
node->next = NULL;
if(l.head == NULL){
//Empty list
l.head = node;
l.tail = node;
} else {
l.tail -> next = node;
l.tail = node;
l.tail -> next = NULL;
}
return l;
}
void l_print(list_cl l){
l_node *node = NULL;
node = l.head;
while(node != NULL){
client *cliente = &node->person;
printf("ID Element: %d | Name: %s Surname: %s Fiscal code: %s", node->id, cliente->first_name, cliente->last_name, cliente->cf);
node = node->next;
}
}
CL_LIST.H
#include "client.h"
typedef struct _node {
unsigned int id;
client person;
struct _node *next;
} l_node;
typedef struct {
l_node *head;
l_node *tail;
} list_cl;
#define L_EMPTYLIST_CL {NULL,NULL}
CLIENT.H
typedef struct {
char cf[17];
char *first_name;
char *last_name;
} client;

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

Item extraction from a list in C

I wrote a function to delete and extract an Item from a list following the usual algorithm for extraction, but while it scans the list it deletes all the items before the searched element.
I am probably missing some pointer being dereferenced but I can't really see where...
Thank you in advance for the help.
Here's the full code.
//DATA STRUCTURE
typedef struct{//EQUIPMENT
int inUse;
object **arrEquip;
}equip;
typedef struct{//PG
char code[MAXL];
char name[MAXL];
char class[MAXL];
equip equip_t;
stats stats_t;
}pg;
typedef struct nodePg theNodePg, *link;
struct nodePg{ //NODE
pg pg_t;
link next;
};
typedef struct{//LIST WRAPPER
link head;
link tail;
int nPg;
}tabPg;
int main(){
tabPg tabPg_t;
tabInv tabInv_t;
int choice;
tabPg_t.head = NULL;
tabPg_t.nPg = 0;
do{
printMenu(&choice);
runSelectedFun(&tabPg_t, &tabInv_t, choice);
}while(choice != 0);
return 0;
}
void runSelectedFun(tabPg *tabPg_t, tabInv *tabInv_t, int choice){
//[...]
pgExtraction(&tabPg_t->head);
//[...]
}
void pgExtraction(link *head){//eliminarlo dalla lista effettivamente
char toBeDeleted[MAXL];
theNodePg deleted;
int flag = 0;
printf("\nInserisci il codice del personaggio da eliminare");
scanf("%s", toBeDeleted);
deleted = extraction(head, toBeDeleted, &flag);
if(flag == 1){
printf("\nPersonaggio %s eliminato con successo!", deleted.pg_t.code);
}
else printf("\nIl codice inserito non ha corrispondenze all'interno della lista PG!\n");
}
theNodePg extraction(link *head, char *code, int *flag){
link *xp,t;
theNodePg deletedPg = {0};
for (xp = head; xp != NULL; xp = &(*xp)->next) {
if (strcmp((*xp)->pg_t.code, code) == 0) {
t = (*xp);
*xp = (*xp)->next;//eliminazione
deletedPg = *t;
free(t);
*flag = 1;
break;
}
}
return deletedPg;
}

How to insert multiple data in linked list

This program asks for two data ( a name and an id), and then stores them in a linked list and then it should output all the data one by one.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Test
{
char name[16];
int id;
};
typedef struct Node {
struct Test structure;
struct Node * next;
}TNode;
typedef TNodo* Node;
void NewDatainNode(struct Test p, Node *pp)
{
TNode *temp;
temp = malloc(sizeof(struct Node));
temp->structure = p;
temp->next = NULL;
*pp = temp;
}
void ReadData(struct Test * p)
{
printf("\nName:");
scanf(" %s", p->name);
printf("\nID:");
scanf(" %d", &p->id);
}
void ViewNodes(Node node)
{
while(node != NULL)
{
printf("%s %d\n",node->structure.name, node->structure.id);
node = node->next;
}
}
int Menu()
{
int c;
printf("\n\tM E N U ***\n"
"1 - New\n"
"2 - Print\n"
"0 - Exit\n"
"\n>> ");
scanf(" %d", &c);
return c;
}
int main()
{
int c;
struct Prova test;
struct Node * list = NULL;
do {
c = Menu();
switch (c)
{
case 1: ReadData(&test);
NewDatainNode(test, &list);break;
case 2: ViewNodes(lista); break;
default: c = 0;
}
} while (c != 0);
return 0;
}
The problem is that it outputs only the last data that has been inserted, what should i do to make it output all the data retrieved in function NuovaPrenotazione()?.
UPDATE: Now the function NewDatainNodes() looks like this:
void NewDatainNode(struct Test p, Node *pp)
{
TNode *temp;
temp = malloc(sizeof(struct Node));
temp->structure = p;
temp->next = *pp;
*pp = temp;
}
Thanks to Sandeep for the correction, the function works even without a return value,the problem was temp->structure = NULL.
This question is exactly duplicate copy of a question posted yesterday and marked as duplicate. But, here is your working code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
struct Prova
{
char nome[16];
int id;
};
typedef struct Node {
struct Prova struttura;
struct Node * next;
}TNodo;
typedef TNodo* Nodo;
Nodo NuovaPrenotazione(struct Prova p, Nodo pp)
{
Nodo temp;
temp = (Nodo)malloc(sizeof(struct Node));
temp->struttura = p;
temp->next = pp;
pp = temp;
return pp;
}
void LeggiPrenotazione(struct Prova * p)
{
printf("\nNome Cliente:");
scanf(" %s", p->nome);
printf("\nID:");
scanf(" %d", &p->id);
}
void Visualizza(struct Prova p)
{
printf("%s %d\n", p.nome, p.id);
}
void VisualizzaPrenotazione(Nodo nodo)
{
while(nodo != NULL)
{
Visualizza(nodo->struttura);
nodo = nodo->next;
}
}
int Menu()
{
int scelta;
printf("*** M E N U ***\n"
"1 - New\n"
"2 - Print\n"
"0 - Esci\n"
"Scelta --> ");
scanf(" %d", &scelta);
return scelta;
}
int main()
{
int scelta;
struct Prova test;
Nodo lista = NULL;
do {
scelta = Menu();
switch (scelta)
{
case 1: LeggiPrenotazione(&test);
lista = NuovaPrenotazione(test, lista);
break;
case 2: VisualizzaPrenotazione(lista); break;
default: scelta = 0;
}
} while (scelta != 0);
return 0;
}
Update: Here is the output

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