打印出链表的输入[C]

时间:2016-06-12 12:14:39

标签: c linked-list

我写了一个链表并设法添加了文件支持。现在命令提示输出存在问题。最后pokemon->namepokemon->number输出神秘。不知怎的,我认为我将最后一批数据保存到内存中时出错,因为它实际上已正确保存到文件中。

这是代码(代码后的输入测试)

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;
}


}

我尝试的输入是:

  

宠物小精灵名称:dudu Pokemon Nummer:3
  宠物小精灵名称:达达口袋妖怪Nummer:3
  宠物小精灵名称:dudi Pokemon Nummer:23
  cmd的输出为:
  姓名:dudu
  Nummer:3
  姓名:dada
  Nummer:3
  姓名:dudi
  Nummer:23
  姓名:Ót
  Nummer:7607776

这里发生了什么?

2 个答案:

答案 0 :(得分:1)

好的,问题在于构建链表的方式 - 只要在调试器下执行代码,它就会变得微不足道 - &gt;你应该真的学会这样做; - )

您正确地将头部保存在firstPtr中,但是您开始循环使用空的但已经创建的链接元素。这就是addPokemon中发生的事情:

  • 初始部分:分配一个新项目并读取其值,分配一个新项目并将其链接到第一个:first(dudu) - &gt;这个(空)
  • 首先进入循环:第一次(dudu) - &gt;达达 - &gt;空
  • 第二次循环:第一次(dudu) - &gt;达达 - &gt; dudi - &gt;空
  • 在循环结束后,你把一个空,但是一步太远了:第一个(dudu) - &gt; dada-&GT; dudi - &gt;空 - &gt; NULL

如何解决:

你应该在将值存储到循环中之前在循环中分配一个新项目,并使用指向firstPokemon的thisPokemon启动循环:

...
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++;

}
...

答案 1 :(得分:0)

  

最后pokemon->namepokemon->number正在输出   隐蔽

<强>原因:

原因为什么你得到一个4 th 节点是因为你在每次迭代结束时创建一个空节点,然后在每次迭代的开始 ......

  • 因此,在上一次迭代中,您创建一个空节点并退出循环。
  • 指向您分配next的空节点的NULL成员。
  • 因此,您最终会打印出四个节点,其中最后一个节点为空。

解决方案:

此问题的解决方案是在开头分配内存,正如其他答案所暗示的那样。但是,

  

在你的代码中,你要为两个函数中的头节点和其余节点分别编写所有内容的痛苦

您可以通过使用单个循环来实现您想要的目标......

在这里,我提供了一个功能,您可以在一个循环中完成这项工作:

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;

}

除此之外,我还希望建议以这种方式使用showPokemon()函数:

void showPokemon(pokemonPtr firstPtr){

pokemonPtr thisPokemon = firstPtr;

while (thisPokemon != NULL)
{

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

    thisPokemon = thisPokemon->next;
}


}

您无需为第一个节点和其余节点单独打印:)