I managed to build a linked list displaying the int that I give to it as parameters, but I can't manage to implement a linked list that displays the command line arguments.
For example, ./aout 20 40 60 80 will have as output
[20] [40] [60] [80]
I think the head of the list should become the argv[1], head->next should be the argv[2] etc.
Here is my code for now :
#include <stdlib.h>
#include <stdio.h>
typedef struct s_list t_list;
struct s_list
{
int value;
t_list *next;
};
void add_node_end(t_list **head, int value);
void add_node_start(t_list **head, int value);
int remove_first(t_list **head);
int remove_last(t_list *head);
int remove_by_index(t_list **head, int n);
void print_list(t_list *head);
void add_node_end(t_list **head, int value)
{
t_list *current;
current = *head;
while (current->next != NULL)
current = current->next;
current->next = malloc(sizeof(t_list));
current->next->value = value;
current->next->next = NULL;
}
void add_node_start(t_list **head, int value)
{
t_list *new;
new = malloc(sizeof(t_list));
new->value = value;
new->next = *head;
*head = new;
}
int remove_first(t_list **head)
{
t_list *next_node;
int retvalue;
retvalue = -1;
next_node = NULL;
if (*head == NULL)
return (-1);
next_node = (*head)->next;
retvalue = (*head)->value;
free(*head);
*head = next_node;
return (retvalue);
}
int remove_last(t_list *head)
{
t_list *current;
int retvalue;
retvalue = 0;
if (head->next == NULL)
{
retvalue = head->value;
free(head);
return (retvalue);
}
current = head;
while (current->next->next != NULL)
current = current->next;
retvalue = current->next->value;
free(current->next);
current->next = NULL;
return(retvalue);
}
int remove_by_index(t_list **head, int n)
{
t_list *current;
t_list *temp_node;
int retvalue;
int i;
i = 0;
retvalue = -1;
if (n == 0)
return (remove_first(head));
while (i < n - 1)
{
if (current->next == NULL)
return (-1);
current = current->next;
i ;
}
temp_node = current->next;
retvalue = temp_node->value;
current->next = temp_node->next;
free(temp_node);
return(retvalue);
}
void print_list(t_list *head)
{
t_list *current;
current = head;
while (current != NULL)
{
printf("%d\n", current->value);
current = current->next;
}
}
int main(void)
{
t_list *head;
head = NULL;
add_node_start(&head, 10);
add_node_end(&head, 20);
add_node_end(&head, 30);
add_node_end(&head, 40);
add_node_end(&head, 50);
print_list(head);
return (0);
}
Do you have an idea ? Thanks
CodePudding user response:
You need to change the definition of main()
and you need a way to convert strings to integer (atoi()
, strtol()
etc):
int main(int argc, char **argv) {
t_list *head = NULL;
if(argc > 1)
add_node_start(&head, atoi(argv[1]));
for(int i = 2; i < argc; i )
add_node_end(&head, atoi(argv[i]));
print_list(head);
return 0
}
It would be convenient to combine the implementations of add_node_start()
and add_node_end()
into a single function to make it easier for calling code to use. As a bonus add_node_end()
does something sensible (instead of crashing) when called with head
pointing to a NULL
pointer:
void add_node_end(t_list **head, int value) {
if(!*head) {
add_node_start(head, value);
return;
}
t_list *current = *head;
while (current->next != NULL)
current = current->next;
current->next = malloc(sizeof(t_list));
current->next->value = value;
current->next->next = NULL;
}
int main(int argc, char **argv) {
t_list *head = NULL;
for(int i = 1; i < argc; i )
add_node_end(&head, atoi(argv[i]));
print_list(head);
return 0
}
CodePudding user response:
Off topic a bit. Good answer by @Allan Wind.
When it comes to short, simple routines, the variable names can clutter-up the landscape (possibly obscuring problems.) Here's a shorter version of one of your functions:
void print_list( t_list *p ) {
while( p ) {
printf( "%d\n", p->value );
p = p->next;
}
}
If you want the flexibility of both appending and prepending nodes to your linked list, you can combine the two functions into one by passing a third parameter. In this example, when 'atEnd' is 0 (false) the code will prepend the new node to the head of the list. (Conversely, 'appending' to the linked list if 'atEnd' is non-zero.)..
void add_node( int atEnd, t_list **head, int value ) {
t_list *new = malloc( sizeof *new );
/* omitting test for NULL */
new->value = value;
new->next = NULL;
if( atEnd ) {
for( t_list *p = *head; p->next; p = p->next )
;// just marching
p->next = new;
}
else {
new->next = *head;
*head = new;
}
}
Less code and fewer "special purpose" functions reduces the number of lines where bugs might be hiding.