Segmentation Fault with Pointers and Structures - c

This program is supposed to manipulate a student list. Every time I try to add more than one student I get a segmentation fault error. Also, when I try to print the list recursively I get a segmentation fault error. I think it has to do with how I am saving to the structure and/or calling it. I am very new to programming so I'm sure it is something simple. Any ideas?
//Header file declarations.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Structure defintion.
struct student {
int ID;
char name[40];
struct student *next;
};
//Type definition.
typedef struct student Student;
//Function prototypes.
int getChoice();
Student *addToList(Student *List);
void printList(Student *List);
void printListRR(Student *List);
void searchList(Student *List);
/*main function
Objective: This function provides runs a function call based on an option selected the user in another function.
Input: This function recieves no input from the user directly but it is passed their menu selection.
Output: The function outputs error messages and a closing salutation to the user. It returns 0.
*/
int main(void) {
int choice = 0;
Student *SLIST = NULL;
//Call getChoice to get user's selection
choice = getChoice();
//Switch-case for the possible menu selections
while(choice >= 0) {
switch(choice) {
case 0 : printf("Bye...\n"); exit(0);
case 1 : SLIST = addToList(SLIST); break;
case 2 : printList(SLIST); break;
case 3 : printListRR(SLIST); break;
case 4 : searchList(SLIST); break;
default: printf("That is not a valid choice\n");
}
choice = getChoice();
}
if(SLIST) free(SLIST);
return 0;
}
int getChoice() {
int choice = 0;
printf("\n****** MENU ******\n");
printf("1. Add new student to list.\n");
printf("2. Print the student list, beginning to end.\n");
printf("3. Recursively print the student list from the end.\n");
printf("4. Search the list for a student.\n");
printf("0. Quit.\n");
printf("\nEnter your choice: ");
scanf("%d", &choice);
return choice;
}
Student *addToList(Student *List){
Student *studentPtr = (Student *) malloc(sizeof(Student));
printf("Student ID: ");
scanf("%d", &(studentPtr->ID));
printf("Student Name: ");
scanf(" %[^\n]", studentPtr->name);
if(List == NULL){
return studentPtr;
}
Student *nextStudent = List;
while (nextStudent->next != NULL){
nextStudent = nextStudent->next;
}
nextStudent->next = studentPtr;
return List;
}
void printList(Student *List){
while(List != NULL){
printf("%d %s\n", List->ID, List->name);
List = List->next;
}
}
void printListRR(Student *List){
if(List == NULL){
return;
}
printListRR(List->next);
}
void searchList(Student *List){
int idSearch;
printf("Enter student ID to search for: ");
scanf("%d", &idSearch);
while(List != NULL){
if(List->ID == idSearch){
printf("%d %s\n", List->ID, List->name);
return;
}
List = List->next;
}
printf("ID %d not found", idSearch);
}

Try initialising studentPtr->next to NULL in addToList()?

Related

this c program runs without error but search,delete,update funtion is not working

#include<stdlib.h>
#include<string.h>
#include<stdio.h>
struct Node
{
char firstname[100];
char lastname[100];
char number[100];
char mail[100];
struct Node *next;
}*head;
void insert(char* firstname,char* lastname,char* number,char* mail)
{
struct Node * node=(struct Node *)malloc(sizeof(struct Node));
strcpy(node->firstname, firstname);
strcpy(node->lastname, lastname);
strcpy(node->number, number);
strcpy(node->mail, mail);
node->next=NULL;
if(head==NULL)
{
head=node;
}
else{
node->next=head;
head=node;
}
}
void search(char* firstname)
{
struct Node * temp = head;
while(temp!=NULL){
if(temp->firstname==firstname){
printf("Contact Found");
printf("Firstname:%s\n",temp->firstname);
printf("Lastname:%s\n",temp->lastname);
printf("PhoneNumber:%s\n",temp->number);
printf("Mail Id:%s\n",temp->mail);
return;
}
temp = temp->next;
}
printf("%s is not found in the contact \n",firstname);
}
void update(char* firstname)
{
struct Node * temp=head;
while(temp!=NULL){
if(temp->firstname==firstname){
printf("Contact Found");
printf("Enter the new Phone number for %s\n",temp->firstname);
scanf("%s",temp->number);
printf("Contact Updated Successfully\n");
return;
}
temp=temp->next;
}
printf("%s is not found in the contact \n",firstname);
}
void delete(char* firstname)
{
struct Node * temp1 = head;
struct Node * temp2 = head;
while(temp1!=NULL){
if(temp1->firstname==firstname){
printf("Contact Found for deleting\n");
if(temp1==temp2){
head = head->next;
free(temp1);
}
else{
temp2->next = temp1->next;
free(temp1);
}
printf("Contact deleted Successfully\n");
return;
}
temp2=temp1;
temp1=temp1->next;
}
printf("%s is not found in the contact \n",firstname);
}
void display()
{
struct Node * temp=head;
while(temp!=NULL){
printf("Firstname:%s\n",temp->firstname);
printf("Lastname:%s\n",temp->lastname);
printf("PhoneNumber:%s\n",temp->number);
printf("Mail Id:%s\n",temp->mail);
temp = temp->next;
}
}
int main()
{
head = NULL;
int choice;
char firstname[100];
char lastname[100];
char number[100];
char mail[100];
printf("-------Welcome--------\n ");
printf("1.Insert a Contact\n2.Search a Contact\n3.Delete a Contact\n4.Update a Contact\n5.Display all the Contacts");
do
{
printf("\nEnter Choice: ");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("Enter Firstname:");
scanf("%s",firstname);
printf("Enter Lastname:");
scanf("%s",lastname);
printf("Enter PhoneNumber:");
scanf("%s",number);
printf("Enter Mail Id:");
scanf("%s",mail);
insert(firstname,lastname,number,mail);
break;
case 2:
printf("Enter Firstname to Search:");
scanf("%s",firstname);
search(firstname);
break;
case 3:
printf("Enter Firstname to Delete:");
scanf("%s",firstname);
delete(firstname);
break;
case 4:
printf("Enter Firstname to Update:");
scanf("%s",firstname);
update(firstname);
break;
case 5:
display();
break;
}
}while (choice != 0);
}
this c program runs without error but search,delete,update funtion is not working...you can refer the img for more details.
tommorrow i have to submit my mini project..so if anyone knows c program please help me
Enter Choice: 2
Enter Firstname to Search:durai
durai is not found in the contact
Enter Choice: 3
Enter Firstname to Delete:durai
durai is not found in the contact
Enter Choice: 4
Enter Firstname to Update:durai
durai is not found in the contact
these are the errors which i'm getting
For example within the function search you are trying to compare two pointers that point to different extents of memory
if(temp->firstname==firstname){
So the condition evaluates to false even if the pointed strings are equal each other. You have to use the standard string function strcmp
For example
if( strcmp( temp->firstname, firstname ) == 0 ){
Pay attention to that all function parameters that have the type char * should be declared as having the type const char *.
Also it is a bad idea when the functions depend on the global variable head. For example in this case you can not create more than one list in a program.

In C,why is my scanf input inside of a linked list node not being taken despite being mentioned in code?

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#define MAX 30
struct EMP {
int empno;
char empName[MAX];
char designation[MAX];
struct EMP *next;
};
/*********************************************************************/
/* Function to insert a node at the front of the linked list. */
/* front: front pointer, id: employee ID, name: employee name */
/* desg: Employee designation */
/* Returns the new front pointer. */
/*********************************************************************/
struct EMP *insert(struct EMP *front, int id, char name[], char desg[])
{
struct EMP *newnode;
newnode = (struct EMP *)malloc(sizeof(struct EMP));
if (newnode == NULL) {
printf("\nAllocation failed\n");
exit(2);
}
newnode->empno = id;
strcpy(newnode->empName, name);
strcpy(newnode->designation, desg);
newnode->next = front;
front = newnode;
return (front);
} /* End of insert() */
/* Function to display a node in a linked list */
void printNode(struct EMP *p)
{
printf("\nEmployee Details...\n");
printf("\nEmp No : %d", p->empno);
printf("\nName : %s", p->empName);
printf("\nDesignation : %s\n", p->designation);
printf("-------------------------------------\n");
} /* End of printNode() */
/* ******************************************************* */
/* Function to deleteNode a node based on employee number */
/* front: front pointer, id: Key value */
/* Returns: the modified list. */
/* ******************************************************* */
struct EMP *deleteNode(struct EMP *front, int id)
{
struct EMP *ptr;
struct EMP *bptr; /* bptr is pointing to the node behind ptr */
if (front->empno == id) {
ptr = front;
printf("\nNode deleted:");
printNode(front);
front = front->next;
free(ptr);
return (front);
}
for (ptr = front->next, bptr = front; ptr != NULL; ptr = ptr->next, bptr = bptr->next) {
if (ptr->empno == id) {
printf("\nNode deleted:");
printNode(ptr);
bptr->next = ptr->next;
free(ptr);
return (front);
}
}
printf("\nEmployee Number %d not found ", id);
return (front);
} /* End of deleteNode() */
/*****************************************************************/
/* Function to search the nodes in a linear fashion based emp ID */
/* front: front pointer, key: key ID. */
/*****************************************************************/
void search(struct EMP *front, int key)
{
struct EMP *ptr;
for (ptr = front; ptr != NULL; ptr = ptr->next) {
if (ptr->empno == key) {
printf("\nKey found:");
printNode(ptr);
return;
}
}
printf("\nEmployee Number %d not found ", key);
} /* End of search() */
/* Function to display the linked list */
void display(struct EMP *front)
{
struct EMP *ptr;
for (ptr = front; ptr != NULL; ptr = ptr->next) {
printNode(ptr);
}
} /* End of display() */
/* Function to display the menu of operations on a linked list */
void menu()
{
printf("---------------------------------------------\n");
printf("Press 1 to INSERT a node into the list \n");
printf("Press 2 to DELETE a node from the list \n");
printf("Press 3 to DISPLAY the list \n");
printf("Press 4 to SEARCH the list \n");
printf("Press 5 to EXIT \n");
printf("---------------------------------------------\n");
} /* End of menu() */
/* Function to select the option */
char option()
{
char choice;
printf("\n\n>> Enter your choice: ");
switch (choice = getche()) {
case '1':
case '2':
case '3':
case '4':
case '5':
return (choice);
default:
printf("\nInvalid choice.");
}
return choice;
} /* End of option() */
/* The main() program begins */
void main()
{
struct EMP *linkList;
char name[21], desig[51];
char choice;
int eno;
linkList = NULL;
printf("\nWelcome to demonstration of singly linked list\n");
menu(); /* Function call */
do {
choice = option(); /* to choose oeration to be performed */
switch (choice) {
case '1':
printf("\nEnter the Employee Number : ");
scanf("%d", &eno);
printf("Enter the Employee name : ");
fflush(stdin);
gets(name);
printf("Enter the Employee Designation : ");
gets(desig);
linkList = insert(linkList, eno, name, desig);
break;
case '2':
printf("\n\nEnter the employee number to be deleted: ");
scanf("%d", &eno);
linkList = deleteNode(linkList, eno);
break;
case '3':
if (linkList == NULL) {
printf("\nList empty.");
break;
}
display(linkList);
break;
case '4':
printf("\n\nEnter the employee number to be searched: ");
scanf("%d", &eno);
search(linkList, eno);
break;
case '5':
break;
}
} while (choice != '5');
} /* End of main() */
However , when I run the program , the program is not accepting the value for Employee name and directly jumping to Employee designation .
As you can see in the screenshot of the output linked, it is directly jumping to the employee designation without taking input for employee name
Why is this happening ?
Edit 1: I was told to try replacing 'gets' with 'fgets' . Despite doing that , the computer is still now taking the input for employee name and directly jumping to employee designation
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#define MAX 30
struct EMP
{
int empno;
char empName[MAX];
char designation[MAX];
struct EMP *next;
};
/*********************************************************************/
/* Function to insert a node at the front of the linked list. */
/* front: front pointer, id: employee ID, name: employee name */
/* desg: Employee designation */
/* Returns the new front pointer. */
/*********************************************************************/
struct EMP* insert(struct EMP *front, int id, char name[], char desg[])
{
struct EMP *newnode;
newnode = (struct EMP*) malloc(sizeof(struct EMP));
if (newnode == NULL)
{
printf("\nAllocation failed\n");
exit(2);
}
newnode->empno = id;
strcpy(newnode->empName, name);
strcpy(newnode->designation, desg);
newnode->next = front;
front = newnode;
return(front);
} /*End of insert() */
/* Function to display a node in a linked list */
void printNode(struct EMP *p)
{
printf("\nEmployee Details...\n");
printf("\nEmp No : %d", p->empno);
printf("\nName : %s", p->empName);
printf("\nDesignation : %s\n", p->designation);
printf("-------------------------------------\n");
} /*End of printNode() */
/* ********************************************************/
/* Function to deleteNode a node based on employee number */
/* front: front pointer, id: Key value */
/* Returns: the modified list. */
/* ********************************************************/
struct EMP* deleteNode(struct EMP *front, int id)
{
struct EMP *ptr;
struct EMP *bptr; /* bptr is pointing to the node behind ptr */
if (front->empno == id)
{
ptr = front;
printf("\nNode deleted:");
printNode(front);
front = front->next;
free(ptr);
return(front);
}
for(ptr=front->next, bptr=front; ptr!=NULL; ptr=ptr->next, bptr=bptr->next)
{
if (ptr->empno == id)
{
printf("\nNode deleted:");
printNode(ptr);
bptr->next = ptr->next;
free(ptr);
return(front);
}
}
printf("\nEmployee Number %d not found ", id);
return(front);
} /*End of deleteNode() */
/*****************************************************************/
/* Function to search the nodes in a linear fashion based emp ID */
/* front: front pointer, key: key ID. */
/*****************************************************************/
void search(struct EMP *front, int key)
{
struct EMP *ptr;
for (ptr = front; ptr != NULL; ptr = ptr -> next)
{
if (ptr->empno == key)
{
printf("\nKey found:");
printNode(ptr);
return;
}
}
printf("\nEmployee Number %d not found ", key);
} /*End of search() */
/* Function to display the linked list */
void display(struct EMP *front)
{
struct EMP *ptr;
for (ptr = front; ptr != NULL; ptr = ptr->next)
{
printNode(ptr);
}
} /*End of display() */
/* Function to display the menu of operations on a linked list */
void menu()
{
printf("---------------------------------------------\n");
printf("Press 1 to INSERT a node into the list \n");
printf("Press 2 to DELETE a node from the list \n");
printf("Press 3 to DISPLAY the list \n");
printf("Press 4 to SEARCH the list \n");
printf("Press 5 to EXIT \n");
printf("---------------------------------------------\n");
} /*End of menu() */
/* Function to select the option */
char option()
{
char choice;
printf("\n\n>> Enter your choice: ");
switch(choice=getche())
{
case '1':
case '2':
case '3':
case '4':
case '5': return(choice);
default : printf("\nInvalid choice.");
}
return choice;
} /*End of option() */
/* The main() program begins */
void main()
{
struct EMP *linkList;
char name[21], desig[51];
char choice;
int eno;
linkList = NULL;
printf("\nWelcome to demonstration of singly linked list\n");
menu(); /*Function call */
do {
choice = option(); /*to choose oeration to be performed */
switch(choice)
{
case '1':
printf("\nEnter the Employee Number : ");
scanf("%d", &eno);
printf("Enter the Employee name : ");
//fflush(stdin);
fgets(name,MAX,stdin);
printf("Enter the Employee Designation : ");
fgets(desig,MAX,stdin);
linkList = insert(linkList, eno, name, desig);
break;
case '2': printf("\n\nEnter the employee number to be deleted: ");
scanf("%d", &eno);
linkList = deleteNode(linkList, eno);
break;
case '3': if (linkList == NULL)
{
printf("\nList empty.");
break;
}
display(linkList);
break;
case '4': printf("\n\nEnter the employee number to be searched: ");
scanf("%d", &eno);
search(linkList, eno);
break;
case '5': break;
}
} while (choice != '5');
} /*End fo main()*/
Answer to the question in the title
Input is not taken because you're mixing the scanf and gets family of functions. scanf leaves the new line character in the buffer, and then when you call fgets to acquire the new line, but fgets finds a new line as the first character and returns immediately.
Suggestion
Pick only one of the *get* and *scanf* families to handle your input. You can still use fgets to get the input, and then pass it to sscanf, to handle the format and retrieve your values.
Example
do {
choice = option(); /* to choose oeration to be performed */
char line_buffer[128]; // Declare your own line buffer
setbuf(stdin, NULL); // Set stdin to unbuffered
switch (choice) {
case '1':
printf("\nEnter the Employee Number : ");
// put input into line buffer
fgets(line_buffer, sizeof(line_buffer), stdin);
// use sscanf on your line_buffer instead of stdin
sscanf(line_buffer, "%d", &eno);
printf("Enter the Employee name : ");
fgets(name, sizeof(name), stdin);
printf("Enter the Employee Designation : ");
fgets(desig, sizeof(desig), stdin);
linkList = insert(linkList, eno, name, desig);
break;
// ...
The problem here is \n is in buffer stdin when you are taking input using gets(). gets() reads stdin(if no buffer is specified) buffer till \n.
One naive solution would be read an extra character that that will eat up \n.
The idea is you can use any of the following just after using scanf() to consume \n from the buffer,
gets();
getc(stdin);
getchar();

Function to read the data file as nodes in a linked list

My text file reads as this:
George Washington, 2345678
John Adams, 3456789
Thomas Jefferson, 4567890
James Madison, 0987654
James Monroe, 9876543
John Quincy Adams, 8765432
Andrew Jackson, 7654321
Martin Van Buren, 6543210
However, when I run my current code to display I don't get those numbers and end up with random ones, how can I fix this? You can avoid the other functions for now as I am just trying to make sure the file reads into different nodes.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Creates node for holding student's information
struct node
{
char name [50];
int id;
struct node *next;
}*head;
//Create Function Prototypes
void readDataFile ();
void display(struct node *d);
void deleteID(int num);
void deleteName(char dname);
//Main function
int main()
{
//Declare variables
int i, num, intid;
char *name;
char nameDelete [50];
char nameInsert [50];
struct node *n;
//initialize link list
head = NULL;
//Read in file
readDataFile();
//Create list of operations utilized in program
while (1)
{
printf("\nList Operations\n");
printf("===============\n");
printf("1.Insert\n");
printf("2.Display\n");
printf("3.Delete by ID\n");
printf("4.Delete by Name\n");
printf("5.Exit\n");
printf("Enter your choice : ");
if(scanf("%d", &i) <= 0)
{
printf("Enter only an Integer\n");
exit(0);
}
else
{
switch(i)
{
case 1:
printf("Enter the name to insert: ");
gets(nameInsert);
printf("Enter the ID associated with the name: ");
scanf("%d", &intid);
break;
case 2:
if (head == NULL)
printf("List is Empty\n");
else
{
printf("Elements in the list are:\n");
}
display(n);
break;
case 3:
if(head == NULL)
printf("List is Empty\n");
else
{
printf("Enter the ID number to delete: ");
scanf("%d", &intid);
}
break;
case 4:
if(head == NULL)
printf("List is Empty\n");
else
{
printf("Enter name to delete: ");
gets(nameDelete);
}
case 5:
return 0;
default:
printf("Invalid option\n");
}
}
}
return 0;
}
The problem you have is not the reading but the printing.
printf("Student %s has ID %d\n", d->name, &d->id);
You use the address-of operator & when reading with scanf (and family), but when you're printing it will print the address of the variable.
You also have some other problem with the reading of the file, besides what I mentioned in my comment, and that is your none-linking:
temp->next = malloc(sizeof(struct node));
temp = temp->next;
temp->next = NULL;
This will create an extra node at the end of the list, which will be uninitialized meaning that when you use the data it will lead to undefined behavior.
Actually, with the problem mentioned in my comment you will have two extra nodes.

How do I give a choice based on a specific choice for my program?

In my program,I plan to filter choices for the users to get a specific piece of data for the inventory.
For instance,at start of the program, there will be menu that gives user option to add or delete data and then for instance if they say insert then I will give them option to select a car company(i.e. like Toyota or Honda) and once they select that company I will give them choice of all Toyota models they can add in the inventory.This will happen so I can narrow down and do a selected operation on the information I have been given.
The thing is I don't know how to filter out the models for a specific company.I have created different arrays containing different models but I don't know how to display user option of models for that company.
Here is my code..
#include <stdio.h>
#include <stdlib.h>
#define MAX_WORD_LENGTH 20
#define MAX_SIZE 100
typedef struct cardata{
char carname[MAX_WORD_LENGTH];
char carmodel[MAX_WORD_LENGTH];
char caryear[MAX_WORD_LENGTH];
char cartype[MAX_WORD_LENGTH];
int quantity;
}CarData;
struct node{
CarData data;
struct node *next;
struct node *prev;
}*start=NULL;
const char *companyList[10] = {"Toyota", "Honda","Hyundai","Nissan","Mitsubishi","VoksWagon","Acura","Ford","Dodge","GMC"};
const char *companyModels[10] = {toyotaModels,hondamodels,hyundaimodels,nissanmodels,mitsubishimodels,vokswagonmodels,acuramodels,fordmodels,dodgemodels,gmcmodels};
const char *toyotaModels[10]={"Corolla","Camery"}
const char *hondaModels[10]={"Civic","Accord"};
void insert_first(){
struct node *ptr;
char carname[MAX_WORD_LENGTH];
char carmodel[MAX_WORD_LENGTH];
char caryear[MAX_WORD_LENGTH];
char cartype[MAX_WORD_LENGTH];
int carQuantity;
int ch;
printf("\n\n\n1.Toyota \n2.Honda \n3.Hyundai \n4.Nissan \n5.Mitsubishi \n6.Volksvagon \n7.Acura \n8.Ford \n9.Dodge \n10.GMC\n");
printf("\nPress a number to select corresponding car(i.e. 1 for toyota, 2 for honda): ");
scanf("%d", &ch);
strcpy(carname,companyList[ch-1]);
printf("\n\nEnter the car model: ");
scanf("%s", carmodel);
printf("\n\nEnter the car year: ");
scanf("%s", caryear);
printf("\n\nEnter the car type: ");
scanf("%s", cartype);
printf("\n\nEnter the quantity of models: ");
scanf("%d", &carQuantity);
if(start==NULL){
start=(struct node *)malloc(sizeof(struct node));
strcpy(start->data.carname,carname);
strcpy(start->data.carmodel,carmodel);
strcpy(start->data.caryear,caryear);
strcpy(start->data.cartype,cartype);
start->data.quantity=carQuantity;
start->prev=NULL;
start->next=NULL;
}else{
ptr=start;
start=(struct node *)malloc(sizeof(struct node));
strcpy(start->data.carname,carname);
strcpy(start->data.carmodel,carmodel);
strcpy(start->data.caryear,caryear);
strcpy(start->data.cartype,cartype);
start->data.quantity=carQuantity;
start->next=ptr;
}
}
void delete_first(){
struct node *ptr;
char carname[MAX_WORD_LENGTH];
char carmodel[MAX_WORD_LENGTH];
char caryear[MAX_WORD_LENGTH];
char cartype[MAX_WORD_LENGTH];
char modelNumber[MAX_WORD_LENGTH];
int carQuantity;
if(start==NULL){
printf("\n\nLinked list is empty.\n");
}else{
ptr=start;
printf("\nThe car for which the entry is removed is %s \n",ptr->data.carname);
strcpy(start->data.carname,carname);
strcpy(start->data.carmodel,carmodel);
strcpy(start->data.caryear,caryear);
strcpy(start->data.cartype,cartype);
start->data.quantity=carQuantity;
start=start->next;
free(ptr);
}
}
void display()
{
struct node *ptr=start;
int i=1;
if(ptr == NULL){
printf("\nLinklist is empty.\n");
}else{
printf("\nSr. No Make Model Year Type Quantity\n");
while(ptr != NULL){
printf("\n%d.\t%s %s %s %s %d\n", i,ptr->data.carname,ptr->data.carmodel,ptr->data.caryear,ptr->data.cartype,ptr->data.quantity);
ptr = ptr->next;
i++;
}
}
}
int main(void)
{
int ch;
do
{
printf("\n\n\n1. Insert \n2. Delete \n3. Display \n4. Exit\n");
printf("\nEnter your choice: ");
scanf("%d", &ch);
switch(ch)
{
case 1:
insert_first();
break;
case 2:
delete_first();
break;
case 3:
display();
break;
case 4:
exit(0);
default:
printf("\n\nInvalid choice. Please try again. \n");
}
} while(1);
return 0;
}
OP: "don't know how to display user option of models."
You need to dynamically form the question from the selected car company. Suggest not using fixed list sizes (drop the 10) and append a NULL to indicated end of list. Improve error handling by checking scanf result and argument range.
const char **CompanyModels[] = { toyotaModels, hondaModels, 0 /* List is 2 long */};
int ModelPrompt(const char **CompanyModels) {
printf("\n\n\n");
int i;
for (i=0; CompanyModels[i], i++) {
printf("%d.%s \n", d+1, CompanyModels[i]);
}
return i;
}
void insert_first(){
...
// recommend replacing next 2 lines with a CompanyPrompt(companyList);
printf("\n\n\n1.Toyota \n2.Honda \n3.Hyundai \n4.Nissan \n5.Mitsubishi \n6.Volksvagon \n7.Acura \n8.Ford \n9.Dodge \n10.GMC\n");
printf("\nPress a number to select corresponding car(i.e. 1 for toyota, 2 for honda): ");
scanf("%d", &ch);
strcpy(carname,companyList[ch-1]);
int MaxModelIndex = ModelPrompt(CompanyModels[ch]);
int carmodelIndex = -1;
if ((1 != scanf("%d", carmodelIndex)) || (carmodelIndex < 0) || (carmodelIndex > MaxModelIndex)) {
; // handle error
}
strcpy(carmodel, CompanyModels[ch][carmodelIndex]);
// continue with similar code for cartype.

Why my doubly linked list's C implementation creating duplicate values?

I coded for doubly linked list implementation in C. In that, after making insertion of values, i am getting duplication of values. i.e. the last value given by me duplicated in all list items.
My code is as follows
header.h
#include<stdio.h>
#include<stdlib.h>
typedef struct doubly_list
{
int id;
char *name;
struct doubly_list *next;
struct doubly_list *prev;
}node;
void insertfirst(node **,int ,char *);
void insertlast(node **,int ,char *);
doubly_list_insert.c
#include"header.h"
void insertfirst(node **head,int id,char *name)
{
node *tmp=(node *)malloc(sizeof(node));
if(NULL == tmp)
{
printf("\nMemory allocation failed\n");
exit(1);
}
tmp->id=id;
tmp->name=name;
tmp->prev=NULL;
if(*head== NULL)
{
tmp->next=NULL;
*head=tmp;
}
else
{
tmp->next=*head;
(*head)->prev=tmp;
*head=tmp;
}
}
void insertlast(node **head,int id,char *name)
{
if(*head==NULL)
{
insertfirst(head,id,name);
return;
}
node *last=*head;
node *tmp=(node *)malloc(sizeof(node));
if(NULL == tmp)
{
printf("\nMemory allocation failed\n");
exit(1);
}
tmp->id=id;
tmp->name=name;
tmp->next=NULL;
while(last->next!=NULL)
{
last=last->next;
}
last->next=tmp;
tmp->prev=last;
}
doubly_list_traverse.c
#include"header.h"
void traverse(node *head)
{
node *tmp=head;
if(head==NULL)
{
printf("\nList is empty\n");
exit(1);
}
while(tmp!=NULL)
{
printf("%d --> %s\n",tmp->id,tmp->name);
tmp=tmp->next;
}
}
And, here comes the main file,
main.c
#include"header.h"
int main()
{
int choice;
int id;
char name[15];
node *root=NULL;
system("clear");
while(1)
{
printf("\n1.Insert First\n");
printf("\n2.Insert Last\n");
printf("\n3.Traverse\n");
printf("\n4.Exit\n");
printf("\nEnter your choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("\nEnter the employee id : ");
scanf("%d",&id);
printf("\nEnter the employee name : ");
scanf("%s",name);
insertfirst(&root,id,name);
break;
case 2:
printf("\nEnter the employee id : ");
scanf("%d",&id);
printf("\nEnter the employee name : ");
scanf("%s",name);
insertlast(&root,id,name);
break;
case 3:
traverse(root);
break;
case 4:
return 0;
break;
default:
printf("\nPlease enter valid choices\n");
}
}
}
During execution its getting input from me properly,if i insert only one data either first or last.
But if i insert a second one, there comes the problem.
In my case, the id value remains the same. But the 2nd input's name value is duplicated in 1st value.
Why this is happening? Is it anything wrong in passing arguments?
When you create a new node, you set the node name by just copying the pointer to the name. You have to copy the string not the pointer. The strdup function is perfect for this:
tmp->name=strdup(name);
Remember to free the name when you free the nodes.
Edit
What happens when you call insertfirst the first time, is that the name field of the first node points to the name array in main. When you fetch the name for the second node, the contents of the array in main is updated with the new name, and since the pointer in the first node points to that array it seems like the name is duplicated.

Resources