user6451351
user6451351

Reputation:

Printing out the input of a linked list [C]

I wrote a linked list and managed to add filesupport to it. Now there is a problem with the command prompt output. The last pokemon->name and pokemon->number is getting outputted cryptic. Somehow I assume I did a mistake in saving the last batch of data into memory, because it is actually correctly saved into the file.

Here is the code (input testing after the code)

pokemonPtr addPokemon(void){

FILE *filePtr;

//filePtr = fopen ("pokedex.txt", "a");

//if (filePtr == NULL){
    filePtr = fopen ("pokedex.txt","w");
//}

pokemonPtr firstPtr;
pokemonPtr thisPokemon;
firstPtr = NULL;

firstPtr = (pokemon *) malloc(sizeof(pokemon));
firstPtr->name = (char *) malloc(sizeof(char) * POKEMON_LENGTH);

printf ("Enter the name of the Pokemon.\n");
scanf("%s",firstPtr->name);
fprintf(filePtr, "Pokemon Name:%s    ", firstPtr->name);
getchar();
printf ("Enter the number of the Pokemon.\n");
scanf("%d",&firstPtr->number);
fprintf(filePtr, "Pokemon Nummer:%d\n", firstPtr->number);



firstPtr->next = (pokemon *) malloc(sizeof(pokemon));

thisPokemon = firstPtr->next;

int i = 0;

while (i < 2){

    thisPokemon->name = (char *) malloc(sizeof(char) * POKEMON_LENGTH);

    printf ("Enter the name of the Pokemon.\n");
    scanf("%s",thisPokemon->name);
    fprintf(filePtr, "Pokemon Name:%s    ", thisPokemon->name);
    printf ("Enter the number of the Pokemon.\n");
    scanf("%d",&thisPokemon->number);
    fprintf(filePtr, "Pokemon Nummer:%d\n", thisPokemon->number);

    thisPokemon->next =(pokemon *) malloc (sizeof(pokemon));
    thisPokemon = thisPokemon->next;

    i++;

}

thisPokemon->next = NULL;

fclose (filePtr);

return firstPtr;

}

void showPokemon(pokemonPtr firstPtr){

printf ("Name:   %s\n"
        "Nummer: %d\n", firstPtr->name, firstPtr->number);

pokemonPtr thisPokemon = firstPtr->next;

while (thisPokemon != NULL){

    printf ("Name:   %s\n"
            "Nummer: %d\n", thisPokemon->name, thisPokemon->number);

    thisPokemon = thisPokemon->next;
}


}

The input I tried was:

Pokemon Name:dudu Pokemon Nummer:3
Pokemon Name:dada Pokemon Nummer:3
Pokemon Name:dudi Pokemon Nummer:23
The output in cmd was:
Name: dudu
Nummer: 3
Name: dada
Nummer: 3
Name: dudi
Nummer: 23
Name: Ót
Nummer: 7607776

What happened here?

Upvotes: 0

Views: 133

Answers (2)

Cherubim
Cherubim

Reputation: 5457

The last pokemon->name and pokemon->number is getting outputted cryptic

Reason:

The reason why you get a 4th node is because you are creating an empty node at the end of each iteration and then filling it up at the start of each iteration...

  • So during the last iteration you create an empty node and get out of the loop.
  • to this empty node's next member you assign the NULL.
  • Therefore you end up getting four nodes printed in which the final one is empty.

Solution :

The solution to this problem is to assign memory at the beginning as the other answer suggests.But,

In your code, you take the pain of writing everything separately for head node and rest of the nodes in both the functions

You can achieve what you want to do by using a single loop...

here I've provided a function in which you can do that within a single loop:

pokemonPtr addPokemon(void){

FILE *filePtr;

filePtr = fopen ("pokedex.txt","w");

pokemonPtr firstPtr;
pokemonPtr thisPokemon;

int i;

for(i = 0 ; i < 3 ; i++ ) //single loop!
{
    if(i==0)//head node
    {
        thisPokemon =(pokemon *) malloc (sizeof(pokemon));
        firstPtr=thisPokemon;
    }
    else //any other node
    {
        thisPokemon->next =(pokemon *) malloc (sizeof(pokemon));
        thisPokemon=thisPokemon->next;
    }

    //first allocation of memory takes place
    thisPokemon->name = (char *) malloc(sizeof(char) * POKEMON_LENGTH);

    //then you enter details
    printf ("Enter the name of the Pokemon.\n");
    scanf("%s",thisPokemon->name);
    fprintf(filePtr, "Pokemon Name:%s    ", thisPokemon->name);
    printf ("Enter the number of the Pokemon.\n");
    scanf("%d",&thisPokemon->number);
    fprintf(filePtr, "Pokemon Nummer:%d\n", thisPokemon->number);

    //no memory allocated at the end
}

thisPokemon->next=NULL; // the next of last entered node points NULL

fclose (filePtr);

return firstPtr;

}

Apart from this similarly, i'd like to suggest you to use the showPokemon() function this way:

void showPokemon(pokemonPtr firstPtr){

pokemonPtr thisPokemon = firstPtr;

while (thisPokemon != NULL)
{

    printf ("Name:   %s\n"
            "Nummer: %d\n", thisPokemon->name, thisPokemon->number);

    thisPokemon = thisPokemon->next;
}


}

you need not print separately for first node and rest of the nodes :)

Upvotes: 0

Serge Ballesta
Serge Ballesta

Reputation: 148890

Ok, the problem is in the way you build your linked list - it is trivial as soon as you execute the code under a debugger -> you should really learn to do that ;-)

You correctly save the head in firstPtr, but you start you loop with an empty but allready created and link element. So here is what happens in addPokemon:

  • initial part: alloc a new item and read its values allocate a new item and link it to first: first(dudu) -> this(empty)
  • first pass in loop: first(dudu) -> dada -> empty
  • second pass in loop: first(dudu) -> dada -> dudi -> empty
  • after end of loop, you put a null, but one step too far: first(dudu) -> dada-> dudi -> empty -> NULL

How to fix:

You should allocate a new item inside the loop just before storing values in it and start the loop with thisPokemon pointing to firstPokemon:

...
firstPtr->next = NULL;

thisPokemon = firstPtr;

int i = 0;

while (i < 2){

    thisPokemon->next =(pokemon *) malloc (sizeof(pokemon));
    thisPokemon = thisPokemon->next;
    thisPokemon->name = (char *) malloc(sizeof(char) * POKEMON_LENGTH);

    printf ("Enter the name of the Pokemon.\n");
    scanf("%s",thisPokemon->name);
    fprintf(filePtr, "Pokemon Name:%s    ", thisPokemon->name);
    printf ("Enter the number of the Pokemon.\n");
    scanf("%d",&thisPokemon->number);
    fprintf(filePtr, "Pokemon Nummer:%d\n", thisPokemon->number);

    i++;

}
...

Upvotes: 1

Related Questions