Inputting Values in the members of structure through linked list - c

I am working in C. Here, I have a structure Node with data members passengers and station. I have a function which inputs the passenger number and stop Name from the user.
struct Node
{
int stopNo;
int passenger;
char station[50];
struct node* next;
};
I have a function which takes the input as the name of station and passengers no and automatically increase the stopNo by 1.
I am trying to Use a linked list to store the stations.
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int stopNo;
int passenger;
char station[50];
struct node* next;
};
void takeInput(struct Node* head)
{
head->stopNo = head->stopNo +1;
printf("Station Name");
scanf(" %[^\n]s",head->station);
printf("New Passengers ");
scanf("%d",&head->passenger);
}
void printStops(struct Node* head)
{
for(int i=0;i<=head->stopNo;i++)
{
printf("Stop %d. %s with %d passenger",head->stopNo,head->station,head->passenger);
}
}
int main()
{ int n;
struct Node* head = NULL;
struct Node* second = NULL;
//Memory Allocation into heap
head = (struct Node*)malloc(sizeof(struct Node));
second = (struct Node*)malloc(sizeof(struct Node));
while(1){
//Menu
printf("1.Log Stops\n");
printf("2.Print Stop");
printf("3.Exit");
scanf("%d",&n);
switch(n){
case 1:
takeInput(struct Node*);
break;
case 2:
printStops(struct Node*);
break;
case 3:
exit(0);
default:
printf("Enter the numbers from 1 to 2");
}
}
}
I am confused what to pass as an argument through the function.

You are mis-using the linked list concept.
The principle is to dynamically add new nodes at the beginning (simpler) or at the end (slightly more complex). Here, as you already have a function dedicated to feeding the list, you could just allocate the nodes there. A possible way is to pass the address of the current head, and let the function change it. But you have to define a sentinel value to tell the function that you do not want to input more nodes.
In the following code "STOP" is that sentinel:
void takeInput(struct Node **head)
{
int stopNo = 0;
for (;;) {
struct Node *node = malloc(sizeof (*node));
node->stopNo = stopNo++;
node->next = *head;
printf("Station Name");
scanf(" %[^\n]",node->station);
if (strcmp(node->station, "STOP") == 0) { // no more station
free(node);
break;
}
printf("New Passengers ");
scanf("%d",&node->passenger);
*head = node;
}
}
That way, you can iterate the list to print its content:
void printStops(struct Node* head)
{
while (head != NULL)
{
printf("Stop %d. %s with %d passenger\n",head->stopNo,head->station,head->passenger);
head = head->next;
}
}
Finally, you main would become:
int main()
{ int n;
struct Node* head = NULL;
while(1){
//Menu
printf("1.Log Stops\n");
printf("2.Print Stop\n");
printf("3.Exit\n");
scanf("%d",&n);
switch(n){
case 1:
takeInput(&head);
break;
...

Related

How to solve the pointer issue in the double linked list below?

Recently I learnt about doubly linked lists, and I have tried to write some code in C to implement them. The program below is supposed to receive integer inputs form the user and put them into a list with a maximum of ten integers. However, when I input the values and then print them, only the first and last values are output. How would one solve this issue?
Here is the code:
`#include <stdio.h>
#include <stdlib.h>
struct node {
struct node* prev;
int num;
struct node* next;
};
struct node *head,*p;
struct node* create_first_node(int x)
{
struct node *new = (struct node*)malloc(sizeof(struct node));
new->num=x;
new->prev=NULL;
new->next=NULL;
head=new;
p=head;
return new;
}
void add_node(int x)
{
struct node*new=(struct node*)malloc(sizeof(struct node));
new->num=x;
new->prev=p;
p->next=new;
(new->next)=NULL;
new=p;
}
void print_list(){
struct node *temp= head;
printf("\nThe list is:\n");
while (temp!=NULL)
{
printf("%d\t",temp->num);
temp=temp->next;
}
}
int main(){
int in[10];
int len,i;
head=NULL;
printf("How many nodes would you like?(Max=10) \n");
scanf("%d",&len);
for (i = 0; i < len; i++)
{
if (head == NULL && i==0)
{
printf("Enter Value for node %d\n",i+1);
scanf("%d",(in+i));
create_first_node(in[0]);
}
else
{
printf("Enter Value for node %d\n",i+1);
scanf("%d",(in+i));
add_node(in[i]);
}
}
print_list(head);
return 0;
}`

Linked list program only printing last two nodes of list

I wrote a program to create and print a single linked list. I have used structure pointer to structure pointer for modifying the list. When I print the list it only prints last two nodes added.
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *next;
};
struct node * createnode(int num){
struct node * n;
n=(struct node*)malloc(sizeof(struct node));
n->data=num;
n->next=NULL;
return n;
}
void createlist(struct node **head,int num){
struct node *temp=createnode(num);
*head=temp;
return;
}
void options(){
printf("Enter your choice\n");
printf("1.Add at end\n");
printf("2.Add at beginning\n");
printf("3.Add at location\n");
printf("4.Print list\n");
}
void add_end(struct node **head){
int info;
printf("Value: ");
scanf("%d",&info);
if(*head==NULL){
createlist(head,info);
return;
}
struct node *temp=createnode(info);
struct node **end=head;
while((*end)->next!=NULL){
(*end)=(*end)->next;
}
(*end)->next=temp;
}
void print2(struct node *head){
struct node * temp=head;
printf("\nList :");
while(temp!=NULL){
printf("%d ",temp->data);
temp=temp->next;
}
printf("\n");
}
int main(){
struct node *head=NULL;
createlist(&head,5);
int choice=0;
options();
scanf("%d",&choice);
while(1){
switch(choice){
case 1:add_end(&head);
break;
case 4:print2(head);
break;
default:exit(0);
}
options();
scanf("%d",&choice);
}
return 0;
}
Each time, I append 5 to 6 nodes at the end of list and when I print the list, it only prints last to nodes added.
I don't know it is wrong with add_end function or print function.
Your add_line routine incorrectly searches for the last node. The end variable is a pointer to pointer, so it is in a sense equivalent to the head parameter and it is not a temporary value, as it should be. Change the last lines to something like this:
void add_end(struct node **head){
...
struct node *end = *head;
while (end->next) {
end = end->next;
// Original line overwrites the 'head': (*end)=(*end)->next;
}
end->next=temp;
}

Storing data Using Linked List

I am trying to write a c program that ask user some information about a brand and store it into linked list. But whenever user enters data it always overwrites the previous data, instead I wanted it to create new node and store it there. This is what I manage so far. How can I do it without using any temporary nodes.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int count = 1;
struct modelNode{
char name[50];
int year;
int amount;
struct modelNode *next;
};
struct modelNode * addModel(struct modelNode *p);
void getBestModel(struct modelNode *p);
int main(){
int command;
struct modelNode * modelList = NULL;
do
{
printf("1. Add a model\n");
printf("2. Display the model with the highest selling amount\n");
printf("3. Exit\n");
printf("Enter command: ");
scanf("%d", &command);
switch(command)
{
case 1:
addModel(modelList);
printf("test %s\n", modelList->name);
//printf("test %s\n", modelList->next->name);
break;
case 2:
printf("45\n");
break;
case 3:
puts("Bye");
break;
default:
printf("default\n");
}
}while(command != 3);
return 0;
}
struct modelNode * addModel(struct modelNode *p){
int iter = 0;
while(iter<count)
{
p = (struct modelNode*)malloc(sizeof(struct modelNode));
p->next=NULL;
iter++;
}
printf("test %s\n", p->name);
printf("Enter the name: ");
scanf("%s", &p->name);
printf("Enter the release year: ");
scanf("%d", &p->year);
printf("Enter the selling amount: ");
scanf("%d", &p->amount);
p->next=NULL;
printf("test %s\n", p->name);
count++;
}
}
This looks like a school exercise, so i doubt anyone here will solve it for you.
But you should try to insert "at the head" , you don't need temp nodes.
Pass the [head] as a param of function addNodes:
Inside addNodes:
Create [new-node]
Set the "next" pointer from [new-node] to the [head]:
[new-node]->next = [head]
Return [new-node]
Resulting linked list (head is the old-head) :
[new-node] ----> [head]
If you do this twice you'll get this:
[newer-node] -----> [new-node] ----> [head]
And so on....
If you want to insert as "tail" , you just need to traverse the linked list recursively, this way you don't use temp nodes.
If i missed the point, please leave a comment explaining further.
The generic functions for adding a node to a linked list would be
typedef struct node_t {
struct node_t* next;
} node_t;
node_t* add(node_t* list, node_t* new_node) {
if (list == NULL) {
return new_node;
} else {
node_t* tmp = list;
while (tmp->next != NULL) {
tmp = tmp->next;
}
tmp->next = new_node;
return list;
}
}
and you could use it like
node_t* list = NULL;
list = add(list, malloc(sizeof(node_t)));
list = add(list, malloc(sizeof(node_t)));
list = add(list, malloc(sizeof(node_t)));
list = add(list, malloc(sizeof(node_t)));
// list would now be a list of 4 nodes
and if you really don't want to use a tmp variable to walk the list, you can do it like this
void add_without_tmp(node_t* list, node_t* new_node) {
if (list == NULL) {
// some error handling
} else {
while(list->next != NULL) {
list = list->next;
}
list->next = new_node;
}
}
node_t* list = malloc(sizeof(node_t));
add_without_tmp(list, malloc(sizeof(node_t)));
add_without_tmp(list, malloc(sizeof(node_t)));
add_without_tmp(list, malloc(sizeof(node_t)));
// list would now be a list of 4 nodes
Edit: fixed the error with the declaration of node_t and added the missing * to the statement node_t* tmp = list;.

c programming linked list sort names in alphabetical orders [duplicate]

This question already has an answer here:
I m trying to sort the node by score. I do not know what error i am having
(1 answer)
Closed 4 years ago.
The whole code is about asking the user to input the students' names and marks.All the other functions are good except wehn it comes to sorting the list.I am trying to create a function called sortlist() to arrange the names in the linked list in alphabetical order after the user has input the names.
/*void sortlist(){
char t[25];
struct Node*temp=head;
struct Node*temp1=temp->next;
while(temp!=NULL){
if(strcmp(temp->name,temp1->name)>0){
strcpy(t,temp1->name);
strcpy(temp1->name,temp->name);
strcpy(temp->name,t);
}temp=temp->next;
}
}
This is my sortlist() function and the programme crashes once I choose case 1. Is this not the way to implement it?
Here is the full code for the programme:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node {
char name[100];
float marks;
struct Node* next; //next is a pointer that stores the address of the next
node
};
struct Node* head; //head is a pointer that stores the address of first node
void printMenu(); //function that prints the menu of the choices
void Print(); //function that prints the result of ALL the students
void Insert_marks(); //function that insert marks of the students
void Insert_names(); //function that insert the names of the students
void Delete(); //function that delete a particular student
void search(); //function that search ONE student and print his or
// her report
void SaveToFile(); //function that save the data entered in text file
void OpenFile(); //function that read data from the text file
void sortlist();
int main(){
int choice,n;
char strings[25];
char words[25];
head = NULL; // the list is empty now
do{
printMenu();
scanf("%d",&choice);
switch(choice){
case 1:
//Introduce the names of the students
printf("enter the name: \n");
scanf("%s",strings);
Insert_names(strings);
sortlist();
break;
case 2:
// Delete the report for a particular student
printf("enter a position");
scanf("%d",&n);
Delete(n);
break;
case 3:
//Introduce marks for all the students
Insert_marks();
break;
case 4:
// print report for individual student
printf("Enter the name:\n");
scanf("%s",words);
search(words);
break;
case 5:
// print report for all the students
printf("NO\tNames\t\tMarks\n");
Print();
break;
case 6:
//Save the data into a text file
SaveToFile();
break;
case 7:
// read the file
OpenFile();
break;
}
}while(choice!= 8);
}
void Insert_names(char strings[25]){
struct Node*temp= (struct Node*)malloc(sizeof(struct Node)); //creating a
// Node
strcpy(temp->name,strings);
temp->marks=-1;
temp->next=NULL;
if(head == NULL){
head = temp;
return;
}else{
struct Node *p =head;
while(p->next)
p= p->next;
p->next=temp;
}
printf("%s\t%s\n",temp->name,temp->next->name);
}
void Insert_marks(){
float x;
struct Node* temp = head;
while(temp->marks != -1){
temp=temp->next;
}
while(temp != NULL){
printf("enter the marks \n");
scanf("%f",&x);
temp->marks=x;
temp=temp->next;
}
}
void Print(){
struct Node* temp = head;
int i=0;
while(temp!= NULL){
i+=1;
printf("%d\t%s\t\t%f",i,temp->name,temp->marks);
temp=temp->next;
printf("\n");
}
}
void Delete(int n){
struct Node* temp1 = head;
if (n ==1){
head = temp1-> next;
free(temp1);
return;
}
int i;
for (i=0;i<n-2;i++)
temp1 = temp1 ->next;
struct Node* temp2= temp1->next;
temp1->next = temp2-> next;
free(temp2);
}
void sortlist(){
char t[25];
struct Node*temp=head;
struct Node*temp1=temp->next;
while(temp!=NULL){
if(strcmp(temp->name,temp1->name)>0){
strcpy(t,temp1->name);
strcpy(temp1->name,temp->name);
strcpy(temp->name,t);
}
}
}
void search(char words[25]){
struct Node*temp = head;
while(temp!= NULL){
if(strcmpi(temp->name,words)==0){
printf("%s\t%f\n",temp->name,temp->marks);
}
temp=temp->next;
}
}
void SaveToFile(){
FILE* fp;
fp = fopen("studentreport.txt","w");
fprintf(fp,"No\tName\t\tMarks\n");
struct Node* temp = head;
int i=0;
while(temp!= NULL){
i+=1;
fprintf(fp,"%d\t%s\t\t%f",i,temp->name,temp->marks);
fprintf(fp,"\n");
temp=temp->next;
}
fclose(fp);
}
void OpenFile(){
FILE*fopen(),*fp;
int c;
fp = fopen("studentreport.txt","r");
c = getc(fp);
while(c != EOF){
printf("%c",c);
c=getc(fp);
}
fclose(fp);
}
void printMenu(){
printf("1.Introduce Student\n2.Remove student\n3.Introduce marks\n4.Print students report\n5.Print report for all students\n6.Save to file\n7.Retrieve data from file\n8.Exit\n");
}
The problem is here:
void sortlist(){
char t[25];
struct Node*temp=head;
struct Node*temp1=temp->next;
while(temp!=NULL){
if(strcmp(temp->name,temp1->name)>0){ // NOTICE: Dereference of temp1
strcpy(t,temp1->name);
strcpy(temp1->name,temp->name);
strcpy(temp->name,t);
}
temp=temp->next;
}
}
When there is only one element in the list temp1 is NULL and the program crash when you do the string compare.
Maybe you wanted to do:
while(temp1!=NULL){
Further you also have a problem if the list is empty. This needs handling as well.
Besides that the logic seems wrong. temp1 is always the same so there is no way this can sort the list.
In general I think a better approach would be to insert new elements in the correct position instead of having a sort function.

linked list with function

I'm trying to create a program which creates and display linked list.
Now i'm having trouble with my create_list() function, it doesn't create any list.
What i'm doing wrong ?
Sorry for bad english :/
CODE :
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
int main(){
node *start;
start = NULL;
int a,n,on = 1;
while(on == 1){
printf(" \n choose: \n 1 --- create list \n 2 --- display list \n");
scanf("%d",&n);
switch(n){
case 1:
printf("-------------------------------------------- \n");
printf(" Enter the elements. The last element is 0 \n");
printf("-------------------------------------------- \n");
Create_list();
Display_list(start);
break;
case 2:
Display_list(start);
break;
}
}
system("pause");
return 0;
}
void Display_list(node *curr){
if(curr){
while (curr->next != NULL){
printf("%d \n",curr->data);
curr=curr->next;
}
} else {
printf(" \n The list is not created ! \n");
}
}
void Create_list(node *curr){
int i;
node *start = NULL;
if (start == NULL){
curr = (node *)malloc(sizeof(node));
start=curr;
while ( i != 0){
scanf("%d",&i);
if(i == 0){
curr->next=NULL;
curr=start;
} else {
curr->data=i;
curr->next=(node *)malloc(sizeof(node));
curr=curr->next;
}
}
} else {
printf(" \n list already exists ! \n");
}
}
The function Create_List(node *curr) needs some arguments. You are not passing any arguments from main(). Did your code compile?
The function Create_List(node *curr) needs some arguments. You are not passing any arguments from main(). Did your code compile?
What you should do is take a node in main which will store location of first node of the linked list.
void Insert(struct node **q, int num) //Num is the data to be added and **q is the pointer to the first node of the list.
{
struct node *temp, *r;
temp = *q;
if (*q == NULL) {
temp = ((struct node *)malloc(sizeof(struct node)));
temp->data = num;
temp->link = NULL;
*q = temp;
}
else {
while (temp->link != NULL)
temp = temp->link;
r = ((struct node *)malloc(sizeof(struct node)));
r->data = num;
r->link = NULL;
temp->link = r;
}
}
The start in Create_list is not related to the start in main. Since both are local to their respective functions, one can't even see the other. So setting start doesn't actually set start, if you will. :P
You'll need to either bring start outside of the functions and make it global, or pass &start (as a node**) from main into Create_list and modify *start to set the list head. (The latter is generally preferable, as globals are often trouble waiting to happen.)

Resources