I am trying to insert data in a separate linked list based on the value that has been given in the 'Gender' variable.
Please check below how it works with the current implementation and how I am attempting to make it look like.
I think there has to be a change in the insertFirst()
and printList()
function but I am not sure.
Example of how it works now is shown in the the input below:
Insert the code of the person Number 1: 1
Insert the age of the person Number 1: 1
Insert the gender of the person Number 1: 1
Insert the code of the person Number 2: 2
Insert the age of the person Number 2: 2
Insert the gender of the person Number 2: 0
Insert the code of the person Number 3: 3
Insert the age of the person Number 3: 3
Insert the gender of the person Number 3: 1
Code Age Gender
3 3 1
2 2 0
1 1 1
Men
Women
The expected result should be grouped by gender as follows:
MEN
Code Age Gender
3 3 1
1 1 1
WOMEN
Code Age Gender
2 2 0
The code is displayed below:
#include <stdio.h>
#include <stdlib.h>
int N;
typedef struct people { /* a struct for people*/
int code; /* a unique identifier for each person*/
int age;
int gender;
struct people *next;
} ppl;
typedef ppl *pppl;
ppl *head = NULL;
ppl *current = NULL;
//a function to insert nodes
void insertFirst(pppl *q, int code, int age, int gender)
{
//create a link
ppl *link = (ppl *)malloc(sizeof(ppl));
link->code = code;
link->age = age;
link->gender = gender;
//point it to old first node
link->next = head;
//point first to new first node
head = link;
}
//display the list
void printList() {
ppl *ptr = head;
char myStrings[][23] = { "Code", "Age", "Gender" };
int i;
for (i = 0; i <= 3; i ) {
printf("%s\t", myStrings i);
}
printf("\n");
//start from the beginnings
while (ptr != NULL) {
printf("%d\t\%d\t\%d\n", ptr->code, ptr->age, ptr->gender);
ptr = ptr->next;
}
}
int main() {
pppl z1, z2;
int i, code1, age1, gender1;
z1 = NULL;
z2 = NULL;
for (i = 1; i <= 3; i ) {
{
printf("Insert the code of the person Number %d: ",i);
fflush(stdin);
scanf("%d", &code1);
}
printf("Insert the age of the person Number %d: ",i);
fflush(stdin);
scanf("%d", &age1);
{
printf("Insert the gender of the person Number %d: ",i);
fflush(stdin);
scanf("%d", &gender1);
}
if (gender1 == 1)
insertFirst(&z1, code1, age1, gender1); // Here it stores in z1 for men
else
insertFirst(&z2, code1, age1, gender1); // Here it stores in z2 for women
}
//print list
printList();
printf(" Men \n");
printList(z1); // I think if that function took parameters it would work like that for z1 and z2
printf(" Women \n");
printList(z2);
return 0;
}
CodePudding user response:
You're not using your pointer-to list head parameter whatsoever. The very purpose of that argument it to allow updating a specific list. Since you're building two, that parameter should be used for the insertion; not some worthless global head
. Printing would likewise involve those two arguments.
Sans a lot of error checking that should still be added, the idea is something like this:
#include <stdio.h>
#include <stdlib.h>
typedef struct people
{ /* a struct for people*/
int code; /* a unique identifier for each person*/
int age;
int gender;
struct people *next;
} ppl;
/*
* Creates a new ppl record, populating with the
* provided arguments.
*/
ppl *make_ppl(int code, int age, int gender, ppl *next)
{
ppl *p = malloc( sizeof *p );
p->code = code;
p->age = age;
p->gender = gender;
p->next = next;
return p;
}
/*
* insert a new node at the head of the provided list.
* the new node becomes the new head via assignment
* through the pointer-to-pointer to node.
*/
void insertFirst(ppl **ppHead, int code, int age, int gender)
{
*ppHead = make_ppl(code, age, gender, *ppHead);
}
/*
* Display the linked list with the provided preamble
* title beforehand. note the 'head' pointer is by-value
* and const, to ensure we do not modify the pointed-to
* data. Further, we can use that pointer directly to
* enumerate the list, with no ill effects to the caller.
*/
void printList(const char *title, const ppl *head)
{
static const char *myStrings[] = {"Code", "Age", "Gender"};
static const size_t n_strings = sizeof myStrings / sizeof *myStrings;
puts(title);
for (size_t i=0; i<n_strings; i)
printf("\t%s", myStrings[i]);
fputc('\n', stdout);
// start from the beginning
while (head != NULL)
{
printf("\t%d\t%d\t%d\n", head->code, head->age, head->gender);
head = head->next;
}
}
/*
* Delete a linked list, starting at the head node
* and following the link chain until exhaustion.
* When done, the caller's pointer will be null and
* the list is fully destroyed.
*/
void deleteList(ppl **ppHead)
{
while (*ppHead)
{
ppl *p = *ppHead;
*ppHead = p->next;
free(p);
}
}
int main()
{
ppl *z1 = NULL;
ppl *z2 = NULL;
int code1, age1, gender1;
for (int i = 1; i <= 3; i )
{
printf("Insert the code of the person Number %d: ", i);
scanf("%d", &code1);
printf("Insert the age of the person Number %d: ", i);
scanf("%d", &age1);
printf("Insert the gender of the person Number %d: ", i);
scanf("%d", &gender1);
if (gender1 == 1)
insertFirst(&z1, code1, age1, gender1); // Here it stores in z1 for men
else
insertFirst(&z2, code1, age1, gender1); // Here it stores in z2 for women
}
printList("Men", z1);
printList("Women", z2);
deleteList(&z1);
deleteList(&z2);
return 0;
}
Output (based on your stated input)
Men
Code Age Gender
3 3 1
1 1 1
Women
Code Age Gender
2 2 0
Also added was a node-creation function and a list cleanup.