Counter Problems and Segmentation Fault (Core Dumped) in C - c

I am currently coding in C and am having trouble trying to selectively search through a linked list of movie information/rating structs. So far I've just gotten a segmentation fault core dump. My current algorithm basically while loops current = current->next except until it reaches NULL in the linked list. It prints out the movie details (through show_structure()) if the user input matches the title information in the linked list.
But to be honest, I want to be able to solve this problem while also implementing where if the user types in a movie title that is not in the linked list it would print out: " Movie does not exist in the database."
Also somehow the counter doesn't increment when I update new movies into the linked list. It keeps staying at 1. Any ideas?
This is my code so far:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
struct movie_node {
char title[250];
int year;
unsigned char rating;
struct movie_node *next;
};
typedef struct movie_node movie_t;
movie_t *first;
movie_t *current;
movie_t *new;
movie_t *make_structure(void);
void fill_structure(movie_t *a);
void show_structure(movie_t *a);
int main()
{
int counter = 0;
char traverse = 1;
char maininput[1];
char searchinput[250];
while (traverse)
{
printf("%d Movie(s) in the database. Update, Search, or Quit (U/S/Q): ", counter);
scanf("%1s", maininput);
if (strcmp("U", maininput) == 0)
{
if (counter == 0)
{
first = make_structure();
current = first;
}
else
{
new = make_structure();
current->next=new;
current=new;
}
counter++; //COUNTER DOESN'T INCREMENT
fill_structure(current);
current->next = NULL;
printf("Movie %s is added to the database.\n\n", current->title);
}
if (strcmp("S", maininput) == 0)
{
printf("Name of the movie: ");
scanf(" %[^\n]%*c", searchinput);
current = first;
do
{
current=current->next;
if (strcmp(searchinput, current->title) == 0) //PROBLEM LIES HERE
{show_structure(current);}
} while(current != NULL);
}
if (strcmp("Q", maininput) == 0)
{
traverse = 0;
}
}
return 0;
}
movie_t *make_structure(void)
{
movie_t *a;
a = (movie_t *)malloc(sizeof(movie_t));
return a;
}
void fill_structure(movie_t *a)
{
printf("Name of the movie: ");
scanf(" %[^\n]%*c", a->title);
printf("Year: ");
scanf("%d", &a->year);
printf("Rating: ");
scanf("%hhu", &a->rating);
}
void show_structure(movie_t *a)
{
printf("Year: %d ", a->year);
printf("Rating: %hhu", a->rating);
}
Output is like this right now:
0 Movie(s) in the database. Update, Search, or Quit (U/S/Q): U
Name of the movie: Pulp Fiction
Year: 1994
Rating: 5
Movie Pulp Fiction is added to the database.
1 Movie(s) in the database. Update, Search, or Quit (U/S/Q): U
Name of the movie: Forrest Gump
Year: 1994
Rating: 5
Movie Forrest Gump is added to the database.
1 Movie(s) in the database. Update, Search, or Quit (U/S/Q): S
Name of the movie: Pulp Fiction
Segmentation fault (core dumped)

Think about this code:
do
{
current=current->next;
if (strcmp(searchinput, current->title) == 0) //PROBLEM LIES HERE
{show_structure(current);}
} while(current != NULL);
When current is the last element, it is not null. You enter the top of the loop, set current to current->next, which is null, and then try to access current->title. But current is NULL. That is a problem. This would be better:
current = first;
while(current != NULL) {
if (strcmp(searchinput, current->title) == 0)
show_structure(current);
current=current->next;
}

this
char maininput[1];
and this
scanf("%1s", maininput);
do not work well with each other.
a %s is a number of characters ending in a \0 so when you write %1s you are expecting at least 2 characters.
instead use fgetc(stdin) to read one character from console.

Related

(C programming) bus error on my linked list

I'm learning to use linkedlist, I feel I already understand the concept but when coding why do I always get an error (bus error)....this code can run, but only until "SCANF the NAME" after that an error appears.
typedef struct Student{
char name[20];
char idNum[10];
int saving;
struct Student *next;
}Student;
Student *head = NULL;
void insert_student(){
char *name,*idNum;
int saving;
Student *current;
Student *new_student;
new_student = (Student*)malloc(sizeof(Student));
// apakah ada memoory kosong?
if(new_student==NULL){
printf("==== YOUR MEMMORY IS FULL! ====\n");
exit(0);
}
printf("Enter your name : ");scanf("%[^\n]s",name);
printf("Enter your Id : ");scanf("%[^\n]s",idNum);
printf("How many your money : Rp");scanf("%d",&saving);
strcpy(new_student->name,name);
strcpy(new_student->idNum,idNum);
new_student->saving = saving;
new_student->next = NULL;
if(head==NULL){
head = new_student;
}
else{
current = head;
while (current->next != NULL)
{
current = current->next;
}
current->next = new_student;
}
}
void print_students(){
Student *current;
if(head==NULL){
printf("==== THERE IS NO STUDENT YET!\n");
exit(0);
}
current = head;
while (current!= NULL)
{
printf("Name : %s",current->name);
printf("id : %s",current->idNum);
printf("Saving : Rp%d",current->saving);
current = current->next;
}
}
int main(){
insert_student();
print_students();
return 0;
}
I'm hoping to create nodes for the dynamic linked-list Student and then display them
printf("Enter your name : ");scanf("%[^\n]s",name);
printf("Enter your Id : ");scanf("%[^\n]s",idNum);
You have to give named and idNum meaningful values before you pass their values to scanf. Instead, you are just passing uninitialized garbage value to scanf, which won't work. You must pass to scanf pointers to the place you want the strings you're reading in to be stored.
For starters it is a bad idea to make the functions to depend on the global variable head. In this case you will not be able to use more than one list in the program.
Within the function insert_student you declared uninitialized pointers name and idNum:
char *name,*idNum;
So using them in the calls of scanf
printf("Enter your name : ");scanf("%[^\n]s",name);
printf("Enter your Id : ");scanf("%[^\n]s",idNum);
invokes undefined behavior.
You need to declare character arrays instead of pointers
char name[20], idNum[10];
Also the format specifications are incorrect.
You should write
printf("Enter your name : "); scanf( " %19[^\n]", name );
printf("Enter your Id : "); scanf( " %9[^\n]", idNum );
Pay attention to the leading space in the format strings It allows to skip white space characters.
Otherwise after this call of scanf
printf("How many your money : Rp");scanf("%d",&saving);
the input buffer will contain the new line character '\n'. So when you will call the function insert_student a second time the first call of scanf (if the format specification does not contain the leading space)
printf("Enter your name : "); scanf( "%19[^\n]", name );
will read an empty string.
Also it is not a flexible approach when the whole program exits if a new node was not allocated.
if(new_student==NULL){
printf("==== YOUR MEMMORY IS FULL! ====\n");
exit(0);
}
It will be better to return to the caller an integer that will report whether the function was executed successfully. For example
int insert_student( void )
{
//...
Student *new_student;
new_student = (Student*)malloc(sizeof(Student));
int success = new_student != NULL;
if ( success )
{
printf("Enter your name : ");scanf("%[^\n]s",name);
printf("Enter your Id : ");scanf("%[^\n]s",idNum);
printf("How many your money : Rp");scanf("%d",&saving);
//...
}
return success;
}

Need help in C programming linked list

I'm creating a program using linked list which will later store in a text file. Basically this program will create an inventory, later update it as well. So I've successfully created the inventory (a function) and I've problem with updating it.
The inventory function is asking user to key in inputs, save into a text file and display it. The updating function has to select a particular item first and after that choosing whether to add or subtract the amount and the text file has to be updated at the same time.
So my problem is, I'm not able to compare the string input from the inventory function with this update function string input. Also, I need to receive an amount of item from user and then add the amount to the existing amount which I had entered in the inventory function earlier.
Visual Studio shows me that String 'code' might not be zero-terminated and String 'update' might not be zero-terminated for the update function.
I'm a beginner so I really need help from all of you, thank you!
This is the linked list codes:
struct donations
{
char supplyName[100], supplyCode[20], donator[150];
int no_ofShipment;
float quantityReceived;
struct donations* ptr;
} *start, *curr, *temp;
This is the inventory function (not a main function and will be changed later its a function for another main menu as the update function)
void main()
{
void details();
int i;
FILE *fp;
start = curr = NULL;
curr = start;
if (start == NULL)
{
start = curr = (struct donations *)malloc(sizeof(struct donations));
for (i = 0; i < 5; i++)
{
curr = (struct donations *)malloc(sizeof(struct donations));
details();
if (i == 0)
start = temp = curr;
else
{
temp->ptr = curr;
temp = curr;
}
}
temp->ptr = NULL;
temp = start;
printf("\n\t Inventory Created Successfully!");
printf("\n\t Recorded to the end of the list!");
}
//create file & print output into the file
if (fopen_s(&fp, "Donation.txt", "w") != 0)
{
printf("\nError");
return;
}
if (!fp)
{
printf("\n Error in opening file!");
//_getch();
return;
}
curr = start;
while (curr)
{
fprintf(fp, "%-30s", curr->supplyName);
fprintf(fp, "%-30s", curr->supplyCode);
fprintf(fp, "%-30s", curr->donator);
fprintf(fp, "%10d", curr->no_ofShipment);
fprintf(fp, "\t%.1f\n", curr->quantityReceived);
curr = curr->ptr;
}
printf("\n\n\t File (records) has been created!");
fclose(fp);
// display output
printf("\n\n\n\tDisplay Inventory");
while (temp)
{
printf("\n\n\n\t Name of Supply: %-30s", temp->supplyName);
printf("Supply Code: %-30s", temp->supplyCode);
printf("Donator: %-30s", temp->donator);
printf("No. of Shipment: %10d", temp->no_ofShipment);
printf("\tQuantity Received: %.1f", temp->quantityReceived);
temp = temp->ptr;
}
}
void details()
{
int i = 0;
system("cls");
printf("\tInventory Creation\t");
printf("\n\n\tEnter Name of Supply: ",(i+1));
gets_s(curr->supplyName);
while (getchar() != '\n');
printf("\n\tEnter Supply Code: ", (i + 1));
gets_s(curr->supplyCode);
while (getchar() != '\n');
printf("\n\tEnter Donator: ", (i + 1));
gets_s(curr->donator);
while (getchar() != '\n');
printf("\n\tEnter No. of Shipment: ", (i + 1));
scanf_s("%d", &curr->no_ofShipment);
while (getchar() != '\n');
printf("\n\tEnter Quantity Received: ", (i + 1));
scanf_s("%f", &curr->quantityReceived);
while (getchar() != '\n');
}
this is my update function, but not finished yet.
void update_DonationQuantity()
{
char code[10];
char update[5];
float quantity, Quantity;
FILE *fp;
printf("\n\tUpdate Donation Quantity\t\n");
printf("\n\n\tSelect donation (CT/HS/FM/SM/OM): ");
gets_s(code);
if (strcmp(code, curr->supplyCode) == 0)
{
printf("\n\tReceived/Distibuted item (+/-): ");
gets_s(update);
while (strcmp(update, "+") && (update, "-") != 0)
{
printf("\n\tWrong input, Try Again");
printf("\n\tReceived/Distibuted item (+/-): ");
gets_s(update);
}
if (strcmp(update, "+") == 0)
{
printf("\n\t Enter received amount: ");
scanf_s("%f", &quantity);
if (fopen_s(&fp, "Donation.txt", "a") != 0)
{
printf("\nError");
return;
}
if (!fp)
{
printf("\n Error in opening file!");
//_getch();
return;
}
curr->quantityReceived = quantity + curr->quantityReceived;
fprintf(fp, "\t%.1f\n", curr->quantityReceived);
}
}
}
There are multiple problems in your code:
struct donations *ptr; is confusing: linked lists usually have a next member to chain the subsequent list element.
void main() is incorrect: the return type of main is int.
void details(); defining a function in a local scope, while allowed is very bad style. You should move this declaration before the start of the main function.
if (start == NULL) is always true.
start = curr = (struct donations *)malloc(sizeof(struct donations)); This line is useless and causes a memory leak: both curr and start are overwritten in the for loop just below.
if (!fp) is redundant: if fopen_s failed, it would have returned 0, otherwise fp must have been set to a valid pointer. Using fopen instead seems simpler and more portable.
printf("\n\n\tEnter Name of Supply: ",(i+1)); the (i+1) argument is useless. The same problem appears in the next printf statements.
gets_s(curr->supplyName); should have a size argument. You might be compiling as C++ for the compiler to accept this. Microsoft has a non-standard template with the same name as the C so call safe function gets_s they forcefully introduced into the C Standard. This is utmostly confusing. You should use fgets(), scanf() or a custom made function to read a string into the destination array, consuming the excess characters and the newline if present. gets_s does not do that, it behavior if the line entered is too long is obscure... The return value should be checked for errors.
while (getchar() != '\n'); is risky: if the stream reaches the end of file before reading a newline, this loop will get stuck in an infinite loop. Furthermore gets_s() should have read the newline, so this loop is only useful for the %d and %f conversions. For this case you could use a flush_stdin() function written this way:
int flush_stdin(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c;
}

How to compare struct fields to variables in C? [duplicate]

This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 1 year ago.
This is part of a deletion function in a linked list program. I'm trying to compare the fields of the current struct node to fields read in by the user for searching. I know my node referencing works as I can print out current fields on their own, but my comparisons in the if statement to the variables does not. How can I compare the fields of current to the user data? Thanks
int deleteEmployee(void)
{
char name[MAX_NAME_LENGTH];
char gender[2];
int age;
char position[MAX_JOB_LENGTH];
int placeInList = 0;
Employee *current = employeeListHead;
Employee *previous = employeeListHead;
printf("Enter details of employee to delete: \n");
printf("Name: \n");
scanf(" %100[^\n]s", name);
scanf("%*[^\n]%*c");
printf("Gender: \n");
scanf(" %1s", gender);
scanf("%*[^\n]%*c");
printf("Age: \n");
scanf(" %d", &age);
scanf("%*[^\n]%*c");
printf("Title: \n");
scanf(" %100[^\n]s", position);
scanf("%*[^\n]%*c");
//while elements in list to search
while(current != NULL)
{
This Specifically
//handling a match on each iteration
if (current->name == name && current->gender == gender && current->age == age && current->position == position)
{
printf("\nIs this the emplyee you'd like to delete? Please confirm (Y/N) %s %s %d %s \n\n", name, gender, age, position);
char choice;
scanf(" %c", &choice);
//if delete is confirmed
if (choice == 'Y' || choice == 'y')
{
//if head of list
if(current == employeeListHead)
{
employeeListHead = current->next;
current = NULL;
return EXIT_SUCCESS;
}
//if tail
else if(current->next == NULL)
{
//change previous nodes pointer
for (int i=0; current!=NULL && i < placeInList-1; i++)
{
previous->next = NULL;
}
current = NULL;
return EXIT_SUCCESS;
}
//if inside list
else
{
for (int i=0; current!=NULL && i < placeInList-1; i++)
{
previous->next = current->next;
}
current = NULL;
return EXIT_SUCCESS;
}
}//end if yes selected to delete
//if delete is confirmed
if (choice == 'N' || choice == 'n')
{
printf("You selected N. Returning to main menu.");
EXIT_FAILURE;
}//end if no selected to delete
}//end if a match
//iterate to next set of nodes
current = current->next;
previous = previous->next;
placeInList++;
}//end iterating through list
printf("Employee not found in system.\n");
return EXIT_FAILURE;
}
You need to use strcmp to compare strings. When you write current->name == name, your program is just comparing the location of two pointers. (But you didn't show the definition of name, so it's hard to be sure.)
Try replacing all string comparisons with something like:
0 == strcmp(current->name, name)

How to delete the record from file

# include <stdio.h>
# include <conio.h>
# include <string.h>
# include <stdlib.h>
struct dnode{
char dlname[20],
dfname[20],
dtel[15];
struct dnode *dnext;
};
int dmenu(); //main menu
void dadd(); //add to list
void dfind(); //search from the list
void dedit(); //edit the record
void ddel(); //delete from the list
void ddisp(); //display all
dnode* sort(dnode* head_node);
typedef struct dnode node;
node *dstart, *dtemp;
int dmenu()
{
int dch;
int i,j,n;
printf(" TELEPHONE DIRECTORY ");
printf(" =================== ");
printf(" \n1. Add ");
printf(" \n2. Find ");
printf(" \n3. Sort ");
printf(" \n4. Delete ");
printf(" \n5. Display All ");
printf(" \n6. EXIT ");
printf(" \nEnter your choice(1-6):");
scanf("%d", &dch);
return dch;
}
void dadd()
{
FILE *fp;
fp=fopen("record.txt","a");
node *dptr,*dprev;
dtemp=(node *)malloc(sizeof(node));
printf("First name: ");
scanf("%s", dtemp->dfname);
printf("Last name:");
scanf("%s", dtemp->dlname);
printf("Telephone No.: ");
scanf("%s", dtemp->dtel);
dtemp->dnext=NULL;
if(dstart==NULL) dstart=dtemp;
else {
dprev=dptr=dstart;
while(strcmp(dtemp->dfname,dptr->dfname)>0){
dprev=dptr;
dptr= dptr->dnext;
if (dptr == NULL) break;
}
if(dptr==dprev) {
dtemp->dnext=dstart;
dstart=dtemp;
}
else if(dptr==NULL)
dprev->dnext=dtemp;
else {
dtemp->dnext=dptr;
dprev->dnext=dtemp;
}
}
fprintf(fp,"%20s %20s %s\n",dtemp->dfname,dtemp->dlname,dtemp->dtel);
fclose(fp);
}
void dfind()
{
FILE *fp;
node *dptr;
char dstr[20];
fp=fopen("record.txt","r");
if(dstart==NULL){
printf("\n\t\t\tTelephone Directory is Empty....\n");
getch();
return;
}
printf("First Name to Find : ");
scanf("%s",dstr);
dptr=dstart;
while(strcmp(dptr->dfname,dstr)!=0)
{
dptr= dptr->dnext;
if (dptr == NULL) break;
}
if(dptr!=NULL) {
printf("First Name : %s\n",dptr->dfname);
printf("Last Name : %s\n",dptr->dlname);
printf("Phone Number : %s\n",dptr->dtel);
}
else {
printf("No Matching Records Found .......\n");
}
fclose(fp);
getch();
}
This is my sorting function, how can i sort the record in file?
dnode* sort(dnode* head_node)
{
dnode *prev, *curr = head_node;
int i, list_size = 0;
/* Determine the size first */
while (curr != NULL)
{
list_size++;
curr = curr->dnext;
}
/* sorting */
for (i = 1; i < list_size; i++)
{
curr = head_node;
while (curr->dnext != NULL)
{
if (strcmp(curr->dfname, curr->dnext->dfname) > 0)
{
dnode* next_node = curr->dnext;
curr->dnext = next_node->dnext;
next_node->dnext = curr;
if (curr == head_node)
head_node = next_node;
else
prev->dnext = next_node;
curr = next_node;
}
prev= curr;
curr = curr->dnext;
}
}
return head_node;
}
Here is my delete function, anyone can help me to solve the delete record in a file?
void ddel()
{
node *dptr,*dprev,*dtemp;
char dstr[20],dyn='n';
struct dnode record;
if(dstart==NULL) {
printf("\n\t\t\tTelephone Directory is Empty....\n");
getch();
return;
}
printf("First Name to Delete : ");
scanf("%s",&dstr);
dprev=dptr=dstart;
while (strcmp(dptr->dfname,dstr)!=0)
{
dprev=dptr;
dptr= dptr->dnext;
if (dptr == NULL)
break;
}
if(dptr!=NULL){
printf("\nDeleting Record.....Confirm [y/n]: ");
dyn=getch();
printf("\n\n---------------------------------------------------------");
printf("\nFirst Name : %s\n",dptr->dfname);
printf("Last Name : %s\n",dptr->dlname);
printf("Phone Number : %s\n",dptr->dtel);
printf("---------------------------------------------------------");
if(dyn=='y') {
if (dptr==dstart) {
dtemp=dstart->dnext;
free(dstart);
dstart=dtemp;
}
else {
dtemp=dptr->dnext;
free(dptr);
dprev->dnext=dtemp;
}
printf("\n\n1 Record Deleted....");
}
else
printf("\n\nRecord not Deleted....");
}
else {
printf("\nNo Matching Records Found .......");
}
getch();
}
void ddisp()
{
FILE *fp;
struct dnode rec;
fp=fopen("record.txt","r");
node *dptr;
if(dstart==NULL) {
printf("\n\t\t\tTelephone Directory is Empty....\n");
getch();
return;
}
printf("\t\t------------------------------\n");
for(dptr=dstart; dptr!=NULL; dptr=dptr->dnext) {
printf("\t\tFirst name: %s", dptr->dfname);
printf("\n\t\tLast name:%s", dptr->dlname);
printf("\n\t\tTelephone No.: %s", dptr->dtel);
printf("\n\t\t------------------------------\n");
}
fclose(fp);
getch();
}
int main()
{
int dch;
int i,j,n;
dstart=(node *)malloc(sizeof(node));
dstart=NULL;
do{
dch=dmenu();
switch(dch) {
case 1: dadd();
break;
case 2: dfind();
break;
case 3: dstart = sort(dstart);;
break;
case 4: ddel();
break;
case 5: ddisp();
break;
}
}while(dch!=6);
}
I have done this code but i can not delete and sorting the record in record.txt file.
To sort a file: read all the records, sort them in memory, then write all of them in the refreshed file (open it in w mode to reset it to an empty file). If there is too many records to handle them in memory you may need to find some alternative (an index would be more appropriate).
To delete: you can't delete something in a file, you need to rewrite most of the file. If there is not so much record, read all of them, remove the one from the memory structure and then rewrite a fresh file. You may find some alternative in the case of too many records.
Ask yourself some questions first on how is your program supposed to deal with adding/storing/searching and deleting records. Only after this start to modify it.
E.g. do you wan to process your data on disk, or in memory? If you prefer to process the phone list in memory in the form of a list – when are you going to synchronize what you have in memory with what you have on disk? As for now it is not clear from your code when you have to open of close the data file, or if our advice should concentrate on deleting/sorting records in memory or on disk.
Without even a sketchy design you have too many ways to change your program.

collect string in loop and printout all the string outside loop

I'm newbie here and there is some question that I want have some lesson from you guys.
For example:
#include <stdio.h>
#include<stdlib.h>
#include<ctype.h>
void main()
{
char name[51],selection;
do
{
printf("Enter name: ");
fflush(stdin);
fgets(name,51,stdin);
printf("Enter another name?(Y/N)");
scanf("%c",&selection);
selection=toupper(selection);
}while (selection=='Y');
//I want to printout the entered name here but dunno the coding
printf("END\n");
system("pause");
}
As I know when the loops perform will overwrite the variable then how I perform a coding that will printout all the name user entered?
I have already ask my tutor and he is ask me to use pointer, can anyone guide me in this case?
You've basically got two options, create a list of all the names, looping through each of them at the end, or concatenate all the names into a string as you read them, and print that whole buffer at the end. The first goes roughly like this:
char ch[2]="Y", names[100][52]; //store up to 100 50-char names (leaving space for \n and \0)
int x, nnames=0;
while(nnames<100 && *ch=='Y'){
fgets(names[nnames++], sizeof names[0], stdin); //since names is a 2d array, look
//only at the length of a row, (in this case, names[0])
fgets(ch, 2, stdin);
*ch = toupper(*ch);
}
for(x=0; x<nnames; x++)
//print names[x].
And the second goes roughly like this:
char names[100*52], *np=names, *ep=names+sizeof names; //an array, the position, and the end
char ch[2]="Y";
while(np<ep && *ch=='Y'){
fgets(np, ep-np, stdin); //read a name, and a newline into the buffer
//note how I use the difference between the end and the position to tell
//fgets the most it can possibly read
np+=strlen(np); //advance the position to the end of what we read.
//same deal with the y/n stuff...
}
printf("%s", names);
Notice the lack of loop at the end, because the whole string is stored in names.
Use a single string to get all names:
char allnames[1000] = "";
do {
//get name in fgets
selection = toupper(selection);
strcat(allnames, selection);
//Check for repetion
} while (/*there is repetion*/);
printf("%s", allnames);
You've to select the size of allnames suitably to store all names.
You can use a linked list to store all the entered names. All data structure books talk about linked list a lot.
#include <stdio.h>
#include <stdlib.h>
struct name_node
{
char name[100];
struct name_node *next;
};
struct name_node* add_name(struct name_node *first, const char *name)
{
struct name_node *p;
/* create our node */
p = (struct name_node*)malloc(sizeof(struct name_node));
strcpy(p->name, name);
p->next = NULL;
/* link our node to the tail */
if (first) {
for (; first->next; first = first->next);
first->next = p;
}
return p;
}
void print_names(struct name_node *first)
{
/* print names stored in the list */
for (; first; first = first->next) {
printf("%s\n", first->name);
}
}
/* free the memory we used */
void destroy_list(struct name_node *first)
{
if (first) {
if (first->next)
destroy_list(first->next);
free(first);
}
}
int main(void)
{
struct name_node *head = NULL;
struct name_node *node;
char name[100];
char selection;
do {
printf("Enter name: ");
fflush(stdin);
fgets(name, 51, stdin);
/* save the user input to a linked list */
/* save head if we don't have head */
node = add_name(head, name);
if (!head)
head = node;
printf("Enter another name?(Y/N)");
scanf("%c", &selection);
selection = toupper(selection);
}
while (selection == 'Y');
/* print the list if we have any data */
if (head)
print_names(head);
/* free the memory we used */
destroy_list(head);
printf("END\n");
system("pause");
return 0;
}

Resources