Linked List Head getting overwritten by tail - c

I am trying to get use to C by implementing different data structures. I am having an issue where when I try to initialize a linked list from command line inputs per while loop iterations, the head keeps getting set to the tail, which is the last command inputted into stdin
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char value[512];
struct node *next;
};
int main(int argc, char *argv[])
{
struct node *head = malloc(sizeof(struct node));
struct node **curr = &head;
int flag = 1;
int c = 0;
while(flag == 1)
{
char cmd[512];
struct node *new_node = malloc(sizeof(struct node));
fgets(cmd, 512, stdin);
cmd[strcspn(cmd, "\n")] = 0;
if (strcmp(cmd,"exit") ==0){
printf("Exiting\n");
break;
} else {
strncpy(new_node->value, cmd, 512);
new_node->value[512 - 1] = '\0';
(*curr)->next = new_node;
*curr = new_node;
}
}
printf("head value: %s\n", head->value);
printf("curr value: %s", (*curr)->value);
return 0;
}
I can't understand why head->value and curr->value end up being the same. Any input is appreciated along with any convention fixes. I am not sure I am writing C in the expected way.
Thanks,
I tried to use different pointer combinations, and I have also tried to copy the command line entry rather than hard setting it.

It is unclear whether you want to insert new nodes to the start of the list or to the end of the list.
If you want to insert new nodes to the start of the list, then you must update head after every list insertion and set the next member of the new node to the old head.
If you instead want to insert new nodes to the end of the list, then you must make curr always point to the next member of the last node of the list, or make it point to head if the list is empty.
You appear to be applying neither of the two options described above. Instead, you are making curr always point to head and making head always point to the most recently created node. You are also making the next pointer of the previous head node point to the new head node. In other words, you are making the next pointers point in the wrong direction. The next pointers should always point away from the head, not toward the head.
Here is an example program which inserts nodes at the start of the linked list:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STRING_LENGTH 512
struct node {
char value[MAX_STRING_LENGTH];
struct node *next;
};
int main( void )
{
struct node *head = NULL;
for (;;) //infinite loop, equivalent to while(1)
{
char cmd[MAX_STRING_LENGTH];
struct node *new_node;
//read one line of input
if ( fgets( cmd, sizeof cmd, stdin ) == NULL )
{
fprintf( stderr, "Input failure!\n" );
exit( EXIT_FAILURE );
}
cmd[strcspn(cmd,"\n")] = '\0';
//check whether user wants to quit
if ( strcmp( cmd, "exit" ) == 0 )
{
printf("Exiting\n");
break;
}
//allocate new node
new_node = malloc( sizeof(struct node) );
if ( new_node == NULL )
{
fprintf( stderr, "Memory allocation failure!\n" );
exit( EXIT_FAILURE );
}
//set value of new node
strcpy( new_node->value, cmd );
//make new node point to old head
new_node->next = head;
//set head to new node
head = new_node;
}
//print content of linked list
printf( "\nThe head points to the address %p.\n", head );
for ( struct node *p = head; p != NULL; p = p->next )
{
printf(
"Node at address %p\n"
" has the value \"%s\"\n"
" and points to the address %p.\n",
(void*)p, p->value, (void*)p->next
);
}
//free the nodes
for ( struct node *p = head; p != NULL; )
{
struct node *temp = p->next;
free( p );
p = temp;
}
return 0;
}
This program has the following behavior:
node1
node2
node3
exit
Exiting
The head points to the address 0x559eea92aad0.
Node at address 0x559eea92aad0
has the value "node3"
and points to the address 0x559eea92a8c0.
Node at address 0x559eea92a8c0
has the value "node2"
and points to the address 0x559eea92a6b0.
Node at address 0x559eea92a6b0
has the value "node1"
and points to the address (nil).
Here is an example program which instead inserts nodes at the end of the linked list:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STRING_LENGTH 512
struct node {
char value[MAX_STRING_LENGTH];
struct node *next;
};
int main( void )
{
struct node *head = NULL;
struct node **pp_next = &head;
for (;;) //infinite loop, equivalent to while(1)
{
char cmd[MAX_STRING_LENGTH];
struct node *new_node;
//read one line of input
if ( fgets( cmd, sizeof cmd, stdin ) == NULL )
{
fprintf( stderr, "Input failure!\n" );
exit( EXIT_FAILURE );
}
cmd[strcspn(cmd,"\n")] = '\0';
//check whether user wants to quit
if ( strcmp( cmd, "exit" ) == 0 )
{
printf("Exiting\n");
break;
}
//allocate new node
new_node = malloc( sizeof(struct node) );
if ( new_node == NULL )
{
fprintf( stderr, "Memory allocation failure!\n" );
exit( EXIT_FAILURE );
}
//set value of new node
strcpy( new_node->value, cmd );
//make new node point to NULL
new_node->next = NULL;
//link new node to existing list
*pp_next = new_node;
//update pp_next to point to the new NULL pointer
pp_next = &new_node->next;
}
//print content of linked list
printf( "\nThe head points to the address %p.\n", head );
for ( struct node *p = head; p != NULL; p = p->next )
{
printf(
"Node at address %p\n"
" has the value \"%s\"\n"
" and points to the address %p.\n",
(void*)p, p->value, (void*)p->next
);
}
//free the nodes
for ( struct node *p = head; p != NULL; )
{
struct node *temp = p->next;
free( p );
p = temp;
}
return 0;
}
This program has the following behavior:
node1
node2
node3
exit
Exiting
The head points to the address 0x5568056a06b0.
Node at address 0x5568056a06b0
has the value "node1"
and points to the address 0x5568056a08c0.
Node at address 0x5568056a08c0
has the value "node2"
and points to the address 0x5568056a0ad0.
Node at address 0x5568056a0ad0
has the value "node3"
and points to the address (nil).

Related

why insertion is not working in my link-list

I am learning linked list Here, I am trying to add node at the first so, I made a structure function to add but i dont know why its not working its only giving this output without adding
7
11
66
After insretion
7
11
66
and also please tell me is there any way to insert element on linked list.
// inserting element on first
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node * next;
};
void link_list_tranversal(struct Node *ptr){
while (ptr!=NULL)
{
printf("%d\n",ptr->data);
ptr=ptr->next;
}
}
struct Node * insert_at_first(struct Node *head,int data){
struct Node *ptr=(struct Node *)malloc(sizeof(struct Node));
ptr->next=head;
ptr->data=data;
return ptr;
}
int main(){
struct Node*head;
struct Node*second;
struct Node*third;
head =(struct Node *) malloc(sizeof(struct Node));
second =(struct Node *) malloc(sizeof(struct Node));
third =(struct Node *) malloc(sizeof(struct Node));
// linking first and secend node
head ->data=7;
head->next=second;
// linking secend and third node
second->data=11;
second->next=third;
// terminate the list at the third
third->data=66;
third->next=NULL;
link_list_tranversal(head);
insert_at_first(head,56);
printf("After insretion\n ");
link_list_tranversal(head);
return 0;
}
After insert_at_first(head,56);, you've created a new node, but head is now pointing to the second node in the list and you have lost track of the newly created node. Simplest fix is to do: head = insert_at_first(head,56);. You can also pass &head and let the function update head.
You need to update the pointer you are storing in head after calling insert_at_first.
// inserting element on first
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node * next;
};
void link_list_tranversal(struct Node *ptr){
while (ptr!=NULL)
{
printf("%d\n",ptr->data);
ptr=ptr->next;
}
}
struct Node * insert_at_first(struct Node *head,int data){
struct Node *ptr=(struct Node *)malloc(sizeof(struct Node));
ptr->next=head;
ptr->data=data;
return ptr;
}
int main(){
struct Node*head;
struct Node*second;
struct Node*third;
head =(struct Node *) malloc(sizeof(struct Node));
second =(struct Node *) malloc(sizeof(struct Node));
third =(struct Node *) malloc(sizeof(struct Node));
// linking first and secend node
head ->data=7;
head->next=second;
// linking secend and third node
second->data=11;
second->next=third;
// terminate the list at the third
third->data=66;
third->next=NULL;
link_list_tranversal(head);
head = insert_at_first(head,56);
printf("After insretion\n ");
link_list_tranversal(head);
return 0;
}
Output:
7
11
66
After insretion
56
7
11
66
A common approach when learning is to add more code and then add more.
Below is the equivalent to your entire program, but done with far fewer lines of code (but lots of comments.)
Please read this and think about what and why of each line.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node { // Using 'typedef' saves LOTS of typing (and reading)
int data; // for now, just one integer
struct Node *next;
} node_t; // conventional naming of a 'type' with "_t" suffix
int mmain() {
int data[] = { 66, 11, 7, 56 }; // your data in compact form
node_t *head = NULL; // ALWAYS initialise variable. Don't let random values happen
for( int i = 0; i < sizeof data/sizeof data[0]; i++ ) { // loop to create LL
// use 'calloc()'. explained below
// do not cast the return pointer from malloc/calloc
node_t *pn = calloc( 1, sizeof *pn );
// malloc/calloc can fail. Halt processing immediately.
if( pn == NULL ) {
fprintf( stderr, "panic! calloc failed.\n" );
exit( 1 );
}
pn->data = data[i]; // for now, just one integer
pn->next = head; // two lines of code "prepend" the new node
head = pn;
// traverse here showing growth
for( pn = head; pn; pn = pn->next )
printf( "%d ", pn->data );
putchar( '\n' );
}
// Avoid memory leaks
// Don't forget to release heap memory when no longer needed.
while( head ) {
node_t *pn = head; // node to be free'd
head = head->next; // remember next
free( pn ); // OFF WITH ITS HEAD!
}
return 0;
}
Output
66
11 66
7 11 66
56 7 11 66
I recommend using calloc() over malloc() when developing code that will grow.
Right now the payload carried by each node is a single integer.
In the thick of it, it is possible to add more elements to the node structure (bigger payload)
yet omit setting every one of the new elements to a known value.
Using calloc() insures that all bytes will consistently be initialised to null.
Then, when testing, you get consistent behaviour (working or not), making it easier to track down bugs.
Notice that "prepending" to a LL is too trivial an operation to "break out" to its own function. "Appending" is not much more difficult, but may justify a function according to your tastes.
Here is the same code again, without comments, for comparison.
typedef struct Node {
int data;
struct Node *next;
} node_t;
int main() {
int data[] = { 66, 11, 7, 56 };
node_t *head = NULL;
for( int i = 0; i < sizeof data/sizeof data[0]; i++ ) {
node_t *pn = calloc( 1, sizeof *pn );
if( pn == NULL ) {
fprintf( stderr, "panic! calloc failed.\n" );
exit( 1 );
}
pn->data = data[i];
pn->next = head;
head = pn;
// traversal for debugging
for( pn = head; pn; pn = pn->next )
printf( "%d ", pn->data );
putchar( '\n' );
}
while( head ) {
node_t *pn = head;
head = head->next;
free( pn );
}
return 0;
}
Even if the program creates new nodes at different locations, you must consider the payload. Don't write a trivial insert() function that adjusts two pointers but receives 27 parameters in the function call.
The function insert_at_first returns a new value of the pointer that points to the head node. You need to assign the returned value to the pointer head to update it
head = insert_at_first(head,56);
Also there is no great sense to allocate nodes in main when you already have the function insert_at_first
You could initially write for example
struct Node *head = NULL;
head = insert_at_first( head, 66 );
head = insert_at_first( head, 11 );
head = insert_at_first( head, 7 );
head = insert_at_first( head, 56 );
Also as the function link_list_tranversal does not change the outputted list then its parameter should be declared with qualifier const
void link_list_tranversal( const struct Node *ptr );
Pay attention to that this function definition
struct Node * insert_at_first(struct Node *head,int data){
struct Node *ptr=(struct Node *)malloc(sizeof(struct Node));
ptr->next=head;
ptr->data=data;
return ptr;
}
is not good because the function will invoke undefined behavior if memory for a node will not allocated successfully.
It is better to declare and define the function the following way
int insert_at_first( struct Node **head, int data )
{
struct Node *ptr = malloc( *ptr );
int success = ptr != NULL;
if ( success )
{
ptr->next = *head;
ptr->data = data;
*head = ptr;
}
return success;
}
And the function can be called like for example
struct Node *head = NULL;
insert_at_first( &head, 66 );
or
struct Node *head = NULL;
if ( !insert_at_first( &head, 66 ) )
{
puts( "Error. No enough memory" );
}

C program to traverse a singly linked lisk

I have written a C program to implement the concept of traversing a singly linked list. The program first creats the list by asking for the user input and then displays/ traverses through the created list. When i run this code, it sucessfully creates the linked list, but on displaying the created list, it produces an infinite loop.
`
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *next;
} *head;
int main(){
struct node *newNode, *temp;
int n;
printf("Enter number of Nodes: ");
scanf("%d",&n);
if(n <= 1){
printf("Invalid Input Nodes should Nodes should be greater than 1");
exit(0);
}
else{
head = (struct node *)malloc(sizeof(struct node));
if(head == NULL){
printf("No Memory Allocation");
exit(0);
}
else{
printf("Node Data 1: ");
scanf("%d",&head -> data);
head -> next = NULL;
temp = head;
}
newNode = (struct node *)malloc(sizeof(struct node));
if(newNode == NULL){
printf("No Memory Allocation");
exit(0);
}
else{
for(int i = 2; i <= n; ++i){
printf("Node Data %d: ",i);
scanf("%d",&newNode -> data);
newNode -> next = NULL;
temp -> next = newNode;
temp = temp -> next;
}
}
//Traversal
struct node *ptr;
ptr = head;
if(ptr == NULL)
{
printf("Empty list..");
}
else
{
while (ptr != NULL){
printf("\n%d",ptr->data);
ptr = ptr -> next;
}
}
}
return 0;
}
`
In this for loop
for(int i = 2; i <= n; ++i){
printf("Node Data %d: ",i);
scanf("%d",&newNode -> data);
newNode -> next = NULL;
temp -> next = newNode;
}
the same pointer newNode is assigned to the data member temp->next that is equivalent to the expression head->next because within the loop the pointer temp is not changed.
You need to allocate new nodes in the loop and reassign the pointer temp.
Also you need to check the entered value for the variable n. For example if n is set to 1 then there will be a memory leak.
And there is neither infinite loop provided that the entered value for the variable n is not equal to INT_MAX.
The program can look the following way
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
struct node
{
int data;
struct node *next;
} *head = NULL;
unsigned int n = 0;
printf( "Enter number of Nodes: " );
scanf( "%u", &n );
if (n != 0)
{
head = malloc( sizeof( struct node ) );
if (!head)
{
puts( "No Memory Allocation" );
exit( 0 );
}
else
{
printf( "Node Data 1: " );
scanf( "%d", &head->data );
head->next = NULL;
unsigned int i = 0;
for (struct node *temp = head; ++i < n; temp = temp->next)
{
if (( temp->next = malloc( sizeof( struct node ) ) ) == NULL)
{
puts( "No Memory Allocation" );
break;
}
temp->next->next = NULL;
printf( "Node Data %u: ", i + 1 );
scanf( "%d", &temp->next->data );
}
for (const struct node *current = head; current != NULL; current = current->next)
{
printf( "%d -> ", current->data );
}
puts( "null" );
}
}
}
The program output is
Enter number of Nodes: 5
Node Data 1: 1
Node Data 2: 2
Node Data 3: 3
Node Data 4: 4
Node Data 5: 5
1 -> 2 -> 3 -> 4 -> 5 -> null
Pay attention to that you need to append the program with the code that will free all the allocated memory.

C - Linked Lists - Deleting Head - Segmentation Fault

I am working on a problem for a class and we're learning linked lists in C. I was given a section of code to complete, specifically the delete a node section and I'm having a problem deleting head. Every time I try to delete head I receive a segmentation fault. Can someone tell me what I'm doing wrong?
EDIT2
My teacher wrote everything but the lookup and delete functions.
I have fixed the glaring errors pointed out by the gentleman from Moscow and Mr. Petriuc, however the code still doesn't run. It does compile, but there is still a problem in head.
Here is the full code:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "linkedList.h"
// keep an unsorted array of char *'s, strings.
/*
Create an empty node, return 0 if fail, 1 if succeed
*/
struct node * createNode() {
struct node *p = (struct node *) malloc(sizeof(struct node));
if (p == NULL) return 0;
p->prev = p->next = NULL;
p->data = NULL;
}
/*
Lookup string in the list, return pointer to node of first occurence, NULL if not found.
*/
struct node * lookup(struct node *head, char *s) {
struct node *p;
for(p=head; p!=NULL; p=p->next){
if(strcmp(s,p->data)==0){
return p;
}
// just like print, but check if strcmp(s, p->data) == 0, and if so then return p
}
return NULL;
}
/*
Insert new string into the linked list, return 1 if success, 0 if fail.
*/
int insert(struct node **head, char *newS, int insertDuplicate) {
struct node *p = lookup(*head, newS);
if (p == NULL || insertDuplicate) {
// create a new node, put it at the front.
p = createNode();
if (p == NULL) return 0;
// put the string in the new node
p->data = (char *) malloc(sizeof(char) * (1 + strlen(newS)));
if (p->data == NULL) return 0;
strcpy(p->data, newS);
// note: make changes and use old head before setting the new head...
p->next = *head; // next of new head is previous head
if (*head != NULL)
(*head)->prev = p; // previous of old head is new head
*head = p; // set the new head
}
return 1;
}
/*
Remove string from list if found, return 1 if found and deleted, 0 o/w.
*/
int delete(struct node **head, char *s) {
struct node *p,*pr,*ne;
// first do a lookup for string s, call lookup.
p=lookup(*head, s);
if(p==*head){
*head = p->next;
free(p);
return 1;
}
if(p!=NULL){
printf("%s",p);
pr = p->prev;
ne = p->next;
free(p->data);
free(p);
if(pr==NULL||ne==NULL){
return 0;
}
pr->next=ne;
ne->prev=pr;
// if lookup returns NULL, done, return 0.
// if lookup returns p, not NULL,
// pr = p->prev, ne = p->next
// set pr->next to ne, ne->prev to pr
// but what if pr or ne is NULL
// and note that we need node **head because if delete head,
// need to update head pointer back in calling function, in
// here if you want head probably do *head. like in insert.
// also, before the pointer to the one you're deleting is gone,
// free p->data and p.
return 1;
}
return 0;
}
void print(struct node *head) {
struct node *p;
for(p = head; p != NULL ; p = p->next) {
printf("%s\n", p->data);
}
}
You are doing
p->next = *head;
But p is not assigned anywhere.
Your function does not make sense. You call the function lookup three times.
Moreover you use pointers that were not initialized like for example
p->next = *head;
or
printf("%s",p);
pr = p->prev;
ne = p->next;
The function can be written the following way
int delete( struct node **head, char *s )
{
int success;
struct node *target = lookup( *head, s );
if ( ( success = target != NULL ) )
{
if ( target->prev != NULL )
{
target->prev->next = target->next;
}
else
{
*head = target->next;
}
if ( target->next != NULL )
{
target->next->prev = target->prev );
}
free( target );
}
return success;
}
Take into account that the second parameter of the function and the corresponding parameter of the function lookup should be declared with qualifier const
int delete( struct node **head, const char *s ) ;
^^^^^
struct node * lookup( struct node *head, const char *s );
^^^^^^
Simplified delete() function. I inlined lookup() because the function as it is is worthless (you need a pointer to pointer, not a pointer to act upon)
/*
Remove string from list if found, return 1 if found and deleted, 0 o/w.
*/
int delete(struct node **head, char *s) {
struct node *tmp;
// first do a lookup for string s, no need to call call lookup.
for( ;*head; head = &(*head)->next ){
if (!strcmp( (*head)->data, s)) break;
}
if (!*head) return 0; // not found
tmp = *head
*head = tmp->next
free(tmp);
return 1;
}

I can't create doubly linked list properly in C

My list head always points to tail. What's the problem?
My linked_list.h:
#ifndef LINKED_LIST
#define LINKED_LIST
struct node
{
char *data;
struct node *nextElement;
struct node *prevElement;
};
void createList(struct node **head, struct node **tail);
void fill_list (char *word, struct node **head, struct node **tail);
#endif
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "linked_list.h"
#include <string.h>
int main()
{
FILE *dataFile;
char *word = (char *) calloc ( 255, sizeof(char) );
/* Create empty list */
struct node *head, *tail;
createList (&head, &tail);
/*------------------------*/
/* Data file open*/
dataFile = fopen("data.txt" ,"r");
if( dataFile == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
/* Data reading */
while (( fscanf(dataFile, "%s", word) ) != EOF )
{
int i = 0;
int wordsCount = 0;
for (i = 0; i <= strlen(word); i++)
{
if ( (word[i] >= 'a') && (word[i] <= 'z') )
wordsCount = wordsCount + 1;
}
if ( wordsCount == strlen(word) )
{
fill_list ( word, &head, &tail );
}
}
fclose(dataFile);
return 0;
};
and linked_list.c:
#include <stdio.h>
#include <stdlib.h>
#include "linked_list.h"
void createList(struct node **head, struct node **tail)
{
*head = NULL;
*tail = NULL;
}
void fill_list ( char *word, struct node **head, struct node **tail )
{
struct node *elem, *temp;
if ( (*head) == NULL )
{
// printf("HEAD = NULL\n");
elem = (struct node *) malloc ( sizeof (struct node) );
elem -> data = word;
elem -> nextElement = NULL;
elem -> prevElement = NULL;
(*head) = elem;
*tail = elem;
// printf("%s\n", (*head) -> data );
}
else
{
// printf("HEAD != NULL\n");
elem = (struct node *) malloc ( sizeof (struct node) );
elem -> data = word;
elem -> nextElement = NULL;
elem -> prevElement = *tail;
*tail = elem;
// printf("%s\n", (*head) -> data );
}
}
My data file: qw erty b cc.
Firstly, head == NULL, so head -> data = 'qw' and it should be as head all the time, but it changes to erty, then b and cc after every loop step.
What I'm doing wrong?
The problem is that you use the same string for all input, and you use that for all nodes. This means all nodes will have its data member point to the same string. This string will of course only contain what you last read into it.
You may want to keep the string buffer in main as a normal array (instead of allocating it on the heap) and use e.g. strdup to duplicate the string for the nodes. Don't forget to free them later though.
A pointer is exactly what it sounds like, it's a variable that points to some other place in memory. You can have many pointers all pointing to the same memory.
In your case you pass the pointer word in the function main to all our calls to fill_list. This means that all nodes you create in fill_list will use the exactly same pointer, and they will all point to the exact same memory.
This means that all nodes in your list will have the data member seem to be the same value and it will always be the last string read into word in the main function.
If you use a function such as strdup it will duplicate the string. I.e. it will allocate completely new memory for the string and copy from the old area into the newly allocate area, and return a pointer to the newly allocated memory.
try this
void fill_list ( char *word, struct node **head, struct node **tail )
{
struct node *elem, *temp;
/* you need to create node first ! */
elem = (struct node *) malloc ( sizeof (struct node));
elem -> data = NULL ;
elem -> data = (char*) malloc( sizeof(char)*255));
if ( elem -> data == NULL )
{
perror("alloc data failed ");
}
if ( (*head) == NULL )
{
// printf("HEAD = NULL\n");
/* call memcpy() function need to #include <string.h> */
elem -> data = memcpy((void*)elem -> data,(void*)word,strlen(word));
elem -> nextElement = NULL;
elem -> prevElement = NULL;
(*head) = elem;
*tail = elem;
// printf("%s\n", (*head) -> data );
}
else
{
// printf("HEAD != NULL\n");
elem -> data = memcpy((void*)elem -> data,(void*)word,strlen(word));
elem -> nextElement = NULL;
elem -> prevElement = *tail;
*tail = elem;
// printf("%s\n", (*head) -> data );
}

Not sure why my code isn't adding and printing my linked list?

Here's my linked list it contains a string version of keys which holds a string representation of contents:
struct node{
char key[10];
char content;
struct node *next;
};
struct node *head=(struct node *) NULL;
struct node *tail=(struct node *) NULL;
struct node * initinode(char *key, char content)
{
struct node *ptr;
ptr = (struct node *) calloc( 1, sizeof(struct node ) );
if( ptr == NULL )
return (struct node *) NULL;
else {
strcpy( ptr->key, key );
ptr->content = content;
return ptr;
}
}
void printnode( struct node *ptr )
{
printf("Key ->%s\n", ptr->key );
printf("Contents ->%d\n", ptr->content );
}
void printlist( struct node *ptr )
{
while( ptr != NULL )
{
printnode( ptr );
ptr = ptr->next;
}
}
void add( struct node *new )
{
if( head == NULL )
head = new;
tail->next = new;
tail->next = NULL;
tail= new;
}
struct node * searchname( struct node *ptr, char *key )
{
while( strcmp( key, ptr->key ) != 0 ) {
ptr = ptr->next;
if( ptr == NULL )
break;
}
return ptr;
}
//-----------------------------add to the list number of files and print list
int file_count = 0;
DIR * dirp;
struct dirent * entry;
dirp = opendir(cwd);
while ((entry = readdir(dirp)) != NULL)
{
if (entry->d_type == DT_REG) { /* If the entry is a regular file */
file_count++;
}
}
printf("%d \n",file_count);
char file=(char)file_count;
closedir(dirp);
ptr=initinode(files, file);
add(ptr);
printlist( head );
//-----------------------------------casting
In addtion to that question I want to add different datatypes to my list in its string represented form. I want to try casting it to a string but it seems the method I used for this would not work on others. And if you suggest diving a void dataype for the list please explain thoroughly.
Thank you
In your code, I have a comment here
void add( struct node *new )
{
if( head == NULL )
head = new;
tail->next = new; // Making tail point to next node
tail->next = NULL; // but, immediately setting tail to NULL --> problem
tail= new; // tail pointing to new but connection to previous node lost
}
I feel that the function could be
void add( struct node *new )
{
if( head == NULL ) {
head = new;
tail = new; // Grow at tail and keep head static
}
else {
tail->next = new; // Connect current node to next
tail= new; // Move tail to new node
tail->next = NULL; // Since this is the last node, set next to NULL
}
}
There is another point to be considered. In this call, printlist( head ); you are passing the head pointer which is getting updated inside the function. I feel it may be a good idea to make a copy of head and pass the same to the function, so that head always points to first element of the list.
P.S: Please avoid naming a variable as new as it is a keyword in C++

Resources