Well, you can do it in linear code, but it's easier if you break down the code flow into whatever job each step has to do. Let's start:
We leave the "intro" unchanged, except for adding stdlib:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
char value[30];
node *next;
};
Now we "shorthand" the declaration (yes, yes, macros are evil, but sometimes, they are useful)
// typedefs are a good alternative here if you dislike macros
#define node_t struct node
Let's start with a helper: adding nodes
node_t* CreateNewNode (node_t* prev)
{
// (type*)malloc(sizeof(type)) is explicit and useful
// but not mandatory in C; you might need it if you write C++
// that shares C code though
// details here: https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc
node_t* node = (node_t*)malloc(sizeof(node_t));
node->next = NULL;
if (prev != NULL)
prev->next = node;
return node;
}
What we're basically doing here is allocating memory for new nodes and because it's a linked list, we're keeping the chain going referencing the previous node.
Now let's add some clean-up. We destroy the linked list. (well, we have to, we allocated memory so now we have to deallocate it)
void DestroyNodes (node_t* head)
{
node_t* current = head;
while (current != NULL)
{
free(current);
current = current->next;
}
}
We c-p the entry-point and the first part of it (replacing the struct with the macro)
int main (void)
{
node_t* current = NULL;
node_t* head = NULL;
while (1)
{
char input[30];
scanf("%29s", &input);
if (strcmp(input, "exit") == 0)
break;
While new
is C++ keyword, and we're playing in C and we showed the compiler that the code has nothing to do with objects, I would really not tempt the compiler gods here, so don't use that as a variable name "just in case".
Now we start using our helpers, along with some different names for the vars:
node_t* prev = current;
current = CreateNewNode(prev);
strcpy(&(current->value)[0], input); // strcpy(current->value, input); is fine too
if (head == NULL)
head = current;
}
Then the deallocation before returning from main()
to avoid memory leaks:
DestroyNodes(head);
So, summarizing:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
char value[30];
node *next;
};
// typedefs are a good alternative here if you dislike macros
#define node_t struct node
node_t* CreateNewNode (node_t* prev)
{
// (type*)malloc(sizeof(type)) is explicit and useful
// but not mandatory in C; you might need it if you write C++
// that shares C code though
// details here: https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc
node_t* node = (node_t*)malloc(sizeof(node_t));
node-> next = NULL;
if (prev != NULL)
prev->next = node;
return node;
}
void DestroyNodes (node_t* head)
{
node_t* current = head;
while (current != NULL)
{
current = current->next;
free(current);
}
}
int main (void)
{
node_t* current = NULL;
node_t* head = NULL;
while (1)
{
char input[30];
scanf("%29s", &input);
if (strcmp(input, "exit") == 0)
break;
node_t* prev = current;
current = CreateNewNode(prev);
strcpy(&(current->value)[0], input); // strcpy(current->value, input); is fine too
if (head == NULL)
head = current;
}
// clean-up
DestroyNodes(head);
return 0;
}