1

I'm to create a LinkedList that has functionalities of adding and printing strings within.

Attaching my code below.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Line {
       char tekst[20];
       struct Line *next;
};

void print(const struct Line* n);
void add(struct Line* n, char t[20], struct Line* next);

int main(void) {
    struct Line lin, *tekst;
    tekst = NULL;
    add(&lin, "ExampleString1", tekst);
    add(&lin, "ExampleString2", tekst);
    print(&lin);

    getch();
    return 0;  
};

void print(const struct Line* n) {
     for ( ; n; n = n->next )
         printf("%s", n->tekst);
     printf("\n");
}

void add(struct Line* n, char t[20], struct Line* next) {
     strcpy(n->tekst,t); // before: n->tekst[20] = t[20];
     n->next = next;
}

It writes some random numbers on the standard output, and then crashes the commandline. I've no idea whether tekst2[20] should even be here (I'm not sure how to call my function arguments here).

My goal is to make a list of strings then be able to add and print them.

6
  • Related: You're passing an indeterminate pointer value as the next parameter to add(), thereby invoking undefined behavior when you evaluate that during your print() enumeration. Just in case you missed that. I.e. tekst in main() is uninitialized. Commented Dec 26, 2013 at 16:47
  • I did not miss that. I'm unaware of how to pass the right next value while calling my add() function. That's one of things I'm asking for to get help with ;) Commented Dec 26, 2013 at 16:48
  • For this specific code, you can address that issue by simply initializing tekst to NULL before sending it as the next value to add(). Honestly, however, this is rather odd for linked list insertion code to begin with. Normally the insertion takes a pointer-to-pointer for the list head, and there are hundreds of examples of this on SO. Commented Dec 26, 2013 at 16:53
  • As stated at the top of my question, it's the first time I'm writing anything alike, and anything at all in C. I don't want to stick to a wrong code, so as long as you are acknowledged with a fixing idea, it wouldn't hurt to share it with me. Commented Dec 26, 2013 at 16:58
  • Are new node insertions supposed to be on the head of the list? or the end of the list? it makes a difference in how the add() function is developed. Commented Dec 26, 2013 at 17:01

2 Answers 2

1

I'm nearly certain this is what you're trying to do:

void add(struct Line** pp, const char *t)
{
    struct Line *p = malloc(sizeof(*p));
    strcpy(p->tekst, t);
    p->tekst2[0] = 0;
    p->next = NULL;

    while (*pp)
        pp = &(*pp)->next;
    *pp = p;
}

Your print() function is using the wrong format specifier for printing a string:

void print(const struct Line* n) 
{
     for ( ; n; n = n->next )
         printf("%s\n", n->tekst);
     printf("\n");
}

Putting it together in main():

int main(void)
{
    struct Line *lst = NULL;

    add(&lst, "SomeTxt");
    add(&lst, "SomeMoreTxt");
    add(&lst, "YetMoreTxt");

    print(lst);

    getch();
    return 0;  
};

Output

SomeTxt
SomeMoreTxt
YetMoreTxt

I leave the proper list cleanup code as well as proper error checking as a task for you.

How It Works

This function utilizes a "pointer-to-pointer" idiom. When you pass &lst from main(), you're passing the address of a pointer variable. Pointers are nothing more than variables that hold addresses to stuff (of the type the pointer it declared, of course). Example:

int a;
int *b = &a;

declares a pointer-to-int, and assigns the address of an int to store within it. On the other hand, this:

int a;
int *b = &a;
int **c = &b;

declares what we had before, but c is declared to be a pointer-to-pointer-to-int. Just like we stored the address of an int in b, notice how we store the address of a int* in c. this is a very powerful feature of the language.

That said, the code works like this:

void add(struct Line** pp, const char *t)
{
    // node allocation stuff. nothing special here
    struct Line *p = malloc(sizeof(*p));
    strcpy(p->tekst, t);
    p->tekst2[0] = 0;
    p->next = NULL;

    // look at the pointer addressed by our pointer-to-pointer pp
    //  while it is not null, store the address of the `next` pointer 
    //  of that node in pp and loop.
    while (*pp)
        pp = &(*pp)->next;

    // pp now holds the address of the pointer we want to set with our new node
    //  it could be the address of the original pointer passed in (if the list was
    //  empty). or the address of some `next` member in the list. We really don't 
    //  care which. All we care about it is it addresses the pointer we need to 
    //  assign our new allocation to, so that is what we do.
    *pp = p;
}

Spend some time on the net researching C and pointers to pointers. They will change the way you think about things like list management. The most important thing to remember is a pointer to pointer does not pointer to some "node"; it points to a pointer that points to a node. That is a pretty heady statement, but do some homework and it will make sense.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your answer. Could you please explain to me, what's going on inside add() ? I also deleted tekst2[20] because there was no need for it. I don't get the struct Line** pp and the rest that uses it.
I believe your comment above line with while (*pp) was supposed to say while it is NOT null
@nobodynoone heh. see? you do understand =P
0

Edited:Use line below (or strncpy) strcpy(n->tekst,t); instead of n->tekst[20] = t[20];

Initialize *test to null

struct Line lin, *tekst=NULL;

Use %s to print text in your program.

printf("%s", n->tekst);

2 Comments

I don't want to get the 21st element of the array. It's just that I thought this is how I represent a string with 20 bytes, since I cannot use "string" type. I don't really think you got my goal that I'd like to obtain
@nobodynoone answer edited as per your query. sorry for earlier answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.