Calling insert function in c from a header file - c

My professor send me a library to insert,delete and search elements in a linked list:
#include <stdlib.h>
struct NODE
{
char AM[12];
char name[40];
int semester;
struct NODE *head;
struct NODE *next;
struct NODE *prev;
};
void init(struct NODE **head)
{
*head=NULL;
}
struct NODE *Search (struct NODE *head,char CODE[],struct NODE **prev)
{
struct NODE *tmp;
*prev=NULL;
tmp=head;
while (tmp!=NULL && tmp->AM<CODE)
{
*prev=tmp;
tmp=tmp->next;
}
if (tmp==NULL)
return NULL;
if (tmp->AM==CODE)
return tmp;
return NULL;
}
struct NODE *Search2 (struct NODE *head,char name[],struct NODE **prev)
{
struct NODE *tmp;
*prev=NULL;
tmp=head;
while (tmp!=NULL && tmp->name<name)
{
*prev=tmp;
tmp=tmp->next;
}
if (tmp==NULL)
return NULL;
if (tmp->name==name)
return tmp;
return NULL;
}
int Insert (struct NODE **H,struct NODE P)
{
struct NODE *cur,*prev;
cur=Search(*H,P.AM,&prev);
if (cur)
return 0;
cur=(struct NODE *)malloc(sizeof P);
*cur=P;
if (prev==NULL)
{
cur->next=*H;
*H=cur;
}
else
{
cur -> next = prev -> next;
prev -> next = cur;
}
return 1;
}
int Delete (struct NODE **H,char AM[])
{
struct NODE *cur,*prev,*next;
cur=Search(*H,AM,&prev);
if (!cur)
return 0;
if (prev==NULL)
cur=next;
else
prev->next=cur->next;
free(cur);
return 1;
}
void traverse (struct NODE *head)
{
struct NODE *cur;
cur=head;
while (cur)
{
printf ("%p\n",cur);
cur=cur->next;
}
}
Now here is a piece of code from the source file that i created in an attempt to insert an element in the linked list:
case 1:printf ("Input AM,name and semester of student: ");
tmp=(struct NODE *)malloc(sizeof(struct NODE));
if (tmp==NULL)
exit(1);
scanf("%s %s %d",tmp->AM,tmp->name,&tmp->semester);
_flag=Insert(&head,*tmp);
if(_flag)
printf ("Student inserted succesfully!\n");
free(tmp);
break;
When i insert the element i get the "Student inserted succesfully" message,but when i call the search function to find that element,it returns NULL (meaning that the element is not in the list).How should i call the Insert function from the header file? (I assume the problem must be in the Insert function).Also in main() i have declared the following two:
struct NODE *head;
struct NODE *tmp;
Should i change something regarding those two?

I think your problem is in the Search() and Search2() functions, where you've got things like this:
while (tmp!=NULL && tmp->AM<CODE)
and
if (tmp->AM==CODE)
return tmp;
You're comparing the pointers, rather than the contents of the strings. If you want to compare the strings, or find which is first alphabetically, use strcmp().
while (tmp!=NULL && strcmp(tmp->AM, CODE) < 0)
and
if (!strcmp(tmp->AM, CODE))
return tmp;
The same goes for the comparison between tmp->name and name in Search2().

Related

Trying to pass and print string into a linked list

So, I am trying to create a linked List where i take in strings from user then add them to the list and then delete the data at position 2. But i am having trouble with scanf (clarified in the output section) and also in the printing section. Any help would be appreciated.
The code
#include <stdio.h>
#include <stdlib.h>
struct node {
char *data;
char *begin;
char *end;
char *posi;
struct node *link;
};
struct node *add_begin(struct node *head, char *data) {
struct node *ptr = malloc(sizeof(*ptr));
ptr->data = data;
ptr->link = head;
return ptr;
}
struct node *add_end(struct node *head, char *data) {
struct node *ptr = malloc(sizeof(*ptr));
ptr->data = data;
ptr->link = NULL;
if (head == NULL) {
return ptr;
} else {
struct node *temp = head;
while (temp->link != NULL) {
temp = temp->link;
}
temp->link = ptr;
return head;
}
}
void add_at_post(struct node* head, char *data, int pos){
struct node *ptr=head;
struct node *ptr2=malloc(sizeof(struct node));
ptr2->data=data;
ptr2->link=NULL;
pos--;
while(pos !=1){
ptr=ptr->link;
pos--;
}
ptr2->link=ptr->link;
ptr->link=ptr2;
}
void delete_post(struct node* head, int position){
struct node*current= head;
struct node*previous= head;
if(head==NULL){
printf("is empty\n");
}
else if (position==1){
head=current->link;
free(current);
current=NULL;
}
else{
while(position!=1){
previous=current;
current=current->link;
position--;
}
previous->link=current->link;
free(current);
current=NULL;
}
}
int main() {
struct node *head = NULL;
char *data;
printf("Print at begin");
scanf("%s",data);
head = add_begin(head,data);//print at beginning of list
printf("Print at end");
scanf("%s",data);
head = add_end(head, data);//print at end of list
printf("Print at Position 2");
scanf("%s",data);
add_at_post(head,data,2);//print at position 2
delete_post(head,2);
for (struct node *ptr = head; ptr; ptr = ptr->link) {
printf("%s\n", ptr->data);
}
return 0;
}
The Expected Output
Print at begin
xxx
Print at end
yyy
Print at Position 2
ZZZ
xxx
zzz
The output I get. It calls the first scanf but skips the other 2. Then ends the RUN.
Print at begin
xxx
Print at end
Print at Position 2
This code is invalid in many places:
data does not reference valid memory
char *data;
printf("Print at begin");
scanf("%s",data);
you should allocate memory for ptr->data and copy as data may reference the same location on every call.
You do not check result of the malloc

Adding a node at the beginning of a Singly Linked List (C)

The code works without error but I cant seem to know why the new node is not being inserted to the beginning of the list. It probably has something to do with the else statement in the first function (insertNode) but I'm not sure, what's going on?
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *link;
};
void insertNode(struct node *head, int x) {
//Create node to be added and add the input integer to it
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp->data = x;
//Check if there are any existing nodes in the list, if not, the let the head be equal to the new temp pointer
if (head == NULL) {
head = temp;
} else {
//If not, then we need to add the node to the beginning
temp->link = head;
head = temp;
printf("Node was added successfully!\n");
}
}
int findsize(struct node *head) {
//Finds the size of the list
struct node *temp = head;
int count = 0;
while (temp != NULL) {
count++;
temp = temp->link;
}
return count;
}
void printData(struct node *head) {
//Prints the elements of the list
struct node *temp = head;
while (temp != NULL) {
printf("Element: %d\n", temp->data);
temp = temp->link;
}
}
void main() {
//Created a node and allocated memory
struct node *head;
head = (struct node *)malloc(sizeof(struct node));
//Added data to the node and created another one linked to it
head->data = 15;
head->link = (struct node *)malloc(sizeof(struct node));
head->link->data = 30;
head->link->link = NULL;
//Used the above function to add a new node at the beginning of the list
insertNode(head, 5);
//Print the size of the list
printf("The size of the list you gave is: %d\n", findsize(head));
//Print the elements of the list
printData(head);
}
When you insert a node at the beginning of the list, you effectively change the beginning of the list, so this new initial node must be returned to the caller. The prototype for insertNode() must be changed to return the list head or to take a pointer to the list head.
Here is a modified version with the first approach:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *link;
};
struct node *insertNode(struct node *head, int x) {
//Create node to be added and add the input integer to it
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
if (temp != NULL) {
temp->data = x;
temp->link = head;
}
return temp;
}
int findsize(struct node *head) {
//Find the size of the list
struct node *temp = head;
int count = 0;
while (temp != NULL) {
count++;
temp = temp->link;
}
return count;
}
void printData(struct node *head) {
//Prints the elements of the list
struct node *temp = head;
while (temp != NULL) {
printf("Element: %d\n", temp->data);
temp = temp->link;
}
}
void main() {
//Created a node and allocated memory
struct node *head = NULL;
//Insert 3 nodes with values 30, 15 and 5
head = insertNode(head, 30);
head = insertNode(head, 15);
head = insertNode(head, 5);
//Print the size of the list
printf("The size of the list you gave is: %d\n", findsize(head));
//Print the elements of the list
printData(head);
//Should free the nodes
return 0;
}

How to change sinlgy linked list to doubly linked list?

I have a program that I am supposed to change it from a singly linked list to a doubly linked list. This means that I use pointer that points to the next node and a pointer that points to previous node.
How do I do this while recycling my previous code. Is there a way to do this with minimum steps involved?
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
//declaring structure
typedef struct node
{
char songName[20];
int songLength;
int copyright;
struct node * next;
}node;
//prototypes
node *create(int n);
void display_recursive(node *n);
int main()
{
int n = 0;
node *head = NULL;
printf("How many entries?\n");
scanf("%d", &n);
//call to create list
head = create(n);
printf("\nThe linked list in order is:\n");
display_recursive(head);
return 0;
}
node *create(int n)
{
node *head = NULL;
node *temp = NULL;
node *p = NULL;
for (int i = 0; i < n; i++)
{
temp = (node*)malloc(sizeof(node));
printf("What is the name of song %d\n", i + 1);
scanf("%s", &temp->songName);
printf("What is the length of song %d (in seconds)?\n", i + 1);
scanf("%d", &temp->songLength);
printf("Is song %d copyrighted?(1 = YES, 0 = NO)\n", i + 1);
scanf("%d", &temp->copyright);
temp->next = NULL;
if (head == NULL)
{
head = temp;
}
else
{
// if not empty, attach new node at the end
p = head;
while (p->next != NULL)
{
p = p->next;
}
p->next = temp;
}
}
return head;
}
void display_recursive(node *n) {
if (!n) {
return;
}
display_recursive(n->next);
printf("Song: %s, ", n->songName);
printf("%d minutes, ",n->songLength);
if (n->copyright == 1)
{
printf("Copyrights\n");
}
else if (n->copyright == 0)
{
printf("No copyrights\n");
}
}
I don't really know how the code should look or what I have to add to achieve a doubly linked list.
You just need a pointer point to previous node
typedef struct node
{
char songName[20];
int songLength;
int copyright;
struct node * next;
struct node* prev;
}node;
just like #T1412 said, you need to add a new member to the structure.
typedef struct node
{
char songName[20];
int songLength;
int copyright;
struct node * next;
struct node* prev;
}node
now you need to modify the create() function so that each node's prev pointer is pointing to previous node, and the HEAD node's prev points to NULL.
Similarly, you need to modify all the linked list related functions to incorporate the prev pointer.
1) strongly suggest changing:
typedef struct node
{
char songName[20];
int songLength;
int copyright;
struct node * next;
}node;
to:
struct NODE
{
char songName[20];
int songLength;
int copyright;
struct NODE * prev;
struct NODE * next;
};
typedef struct NODE node;
Then wherever in the code that it is linking in a new node, add the necessary statement to set the 'prior' field. Remember that the firs node will contain NULL in the 'prior' field.

Can't traverse through a C linked list

Task is to create a linked list consisting of objects. User inputs data for each individual Node in the main and then the object is being passed to push, which creates the list.
The problem comes in the printList function, where the condition for a break is never met.
For some reason the line head = head->next doesn't do anything, as the address of next with every iteration remains the same.
typedef struct Node {
int a;
char asd[30];
struct Node *next;
}Node;
Node *head = NULL;
void push(Node**head, struct Node* object);
void printList(Node *head);
int main() {
struct Node {
int oA;
char oAsd[30];
struct Node *next;
};
struct Node *object = malloc(sizeof(struct Node));
int c = 0;
while (1) {
printf("This int will be stored in Node %d.\n", ++c);
scanf("%d", &object->oA);
getchar();
if (!object->oA) {
break;
}
printf("This string will be stored in Node %d.\n", c);
gets_s(object->oAsd, 30);
if (!(strcmp(object->oAsd, "\0"))) {
break;
}
push(&head, object);
}
printList(head);
return 0;
}
void push(Node ** head, struct Node* object)
{
Node *tmp = malloc(sizeof(Node));
tmp = object;
tmp->next = (*head);
(*head) = tmp;
}
void printList(Node *head) {
if (head == NULL) {
puts("No list exists.");
exit(9);
}
while (1) {
printf("-------------------------------\n");
printf("|Int: <%d> |||| String: <%s>.|\n", head->a, head->asd);
printf("-------------------------------\n");
if (head->next) {
printf("\n\n%p\n\n", head->next);
head = head->next;
}
else {
break;
}
}
}`
There are two major problems in your code:
You define struct Node both outside main and inside main
Here tmp = object; you copy the value of a pointer to another pointer but you really want to copy the value of a struct to another struct, i.e. *tmp = *object;.
Besides that - don't put head as a global variable.
So the code should be more like:
typedef struct Node {
int a;
char asd[30];
struct Node *next;
}Node;
void push(Node**head, struct Node* object);
void printList(Node *head);
int main() {
Node *head = NULL;
struct Node *object = malloc(sizeof(struct Node));
int c = 0;
while (1) {
printf("This int will be stored in Node %d.\n", ++c);
scanf("%d", &object->a);
getchar();
if (!object->a) {
break;
}
printf("This string will be stored in Node %d.\n", c);
gets_s(object->asd, 30);
if (!(strcmp(object->asd, "\0"))) {
break;
}
push(&head, object);
}
printList(head);
return 0;
}
void push(Node ** head, struct Node* object)
{
Node *tmp = malloc(sizeof(Node));
*tmp = *object; // Copy the struct
tmp->next = (*head);
(*head) = tmp;
}
void printList(Node *head) {
if (head == NULL) {
puts("No list exists.");
exit(9);
}
while (1) {
printf("-------------------------------\n");
printf("|Int: <%d> |||| String: <%s>.|\n", head->a, head->asd);
printf("-------------------------------\n");
if (head->next) {
printf("\n\n%p\n\n", head->next);
head = head->next;
}
else {
break;
}
}
}

Create a new node for each entry in a .txt file

Okay so I've been doing a program which would read elements of a txt file using scanf (cmd input redirection). A new node must be created for every entry in the file and add it at the end of the list. Here's my code so far:
struct Elem{
int Atnum;
char Na[31];
char Sym[4];
};
struct nodeTag {
struct Elem entry;
struct nodeTag *pNext; // pointer to the next node
};
typedef struct nodeTag Node;
The function that would initialize it is this:
Node *
InitializeList(Node *pFirst, int n)
{
int i;
Node *head, *temp = 0;
pFirst = 0;
for (i=0; i<n; i++){
head = (Node *)malloc(sizeof(Node));
scanf("%d", &head->entry.AtNum);
scanf("%s", head->entry.Na);
scanf("%s", head->entry.Sym);
if (pFirst != 0)
{
temp->pNext = head;
temp = head;
}
else
{
pFirst = temp = head;
}
fflush(stdin);
temp->pNext = 0;
}
return pFirst;
}
and lastly, print it
void
Print( Node *pFirst )
{
Node *temp;
temp = pFirst;
printf("\n status of the linked list is\n");
while (temp != 0)
{
printf("%d %s %s", temp->entry.AtNum, temp->entry.Na, temp->entry.Sym);
temp = temp -> pNext;
}
}
Now, I can't get the program to run properly. No run-time errors though but the output seems to be garbage. I've been working for hours for this and I cant' get my head around it. Thank you for your help!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Elem
{
int AtNum;
char Na[31];
char Sym[4];
};
struct nodeTag
{
/* entry must be a pointer in order to not lose the values
and/or encounter memory conflicting errors
*/
struct Elem *entry;
struct nodeTag *pNext;
};
typedef struct nodeTag Node;
// insert node at the first location
Node *insertFirst(Node *head, struct Elem *data)
{
Node *node = (Node *) malloc(sizeof(Node));
// fill in data
node->entry = data;
/* point it to old first node
in simple words: "put this node before the head"
*/
node->pNext = head;
// point first to new first node
head = node;
return head;
}
Node *InitializeList(int n)
{
int i;
Node *head = NULL;
struct Elem *data;
for (i = 0; i < n; i++)
{
// allocate memory for the struct Elem of each node
data = (struct Elem*) malloc(sizeof(struct Elem));
scanf("%d", &data->AtNum);
scanf("%s", data->Na);
scanf("%s", data->Sym);
head = insertFirst(head, data);
}
return head;
}
//display the list
void printList(Node *head)
{
Node *ptr = head;
printf("\nStatus of the linked list is:\n");
//start from the beginning
while(ptr != NULL)
{
printf("%d %s %s", ptr->entry->AtNum, ptr->entry->Na, ptr->entry->Sym);
printf("\n");
ptr = ptr->pNext;
}
}
int main(int argc, char *argv[])
{
Node *head;
head = InitializeList(3);
printList(head);
return 0;
}
I hope I didn't come too late! If not, please check this answer as the solution, thanks! :-)

Resources