召唤师 发表于 2020-3-6 09:34:30

单链表的这个代码错误在哪?

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

void addBook(struct Book **library);
void getinput(struct Book *book);
void printfbook(struct Book *library);
void freelibrary(struct Book *book);
struct Book{
        char title;
        char author;
        struct Book *next;
};

void getinput(struct Book *book){
        printf("请输入书名\n");
        scanf("%s",book->title);
        printf("请输入作者\n");
        scanf("%s",book->author);
}

void addBook(struct Book **library){
        struct Book *book,*temp;
        book=NULL;
        temp=NULL;
        book=(struct Book*)malloc(sizeof(struct Book));
        if(book==NULL){
                printf("内存分配失败了");
                exit(1);
        }
        else{
                getinput(book);
        }
        if (*library != 0)               
      {                              
                temp = *library;
                *library = book;
                book->next = temp;
      }
      else                           
      {
                *library = book;
                book->next = NULL;
      }
}

void printfbook(struct Book *library){
        struct Book *book;
        book=library;
        int i=1;
        while(book!=NULL){
        printf("您录入的第%d本书的书名是:%s\n",i,book->title);
        printf("您录入的第%d本书的作者是:%s\n",i,book->author);       
        i++;
        book=book->next;
        }
       
}

void freelibrary(struct Book *library){
        struct Book* temp;//temp跳出函数之后会自动释放,所以不用操心他的存在
        while(library!=NULL){
        temp=library->next;
        free(library);
        library=temp;
        }
}

int main(){
        struct Book *library=NULL;
        addBook(&library);
        char ans;


        while(1){
                printf("是否继续录入书本?Y/N\n");
                scanf("%s",&ans);
        if(ans=='Y'){
                printf("请继续录入书本信息\n");
                addBook(&library);
        }
        else{
        break;
        }
        }
       
        printf("是否打印目录?Y/N\n");
        scanf("%s",&ans);
                if(ans=='Y'){
                        printf("开始打印书目\n");
                        printfbook(library);
                }
                else{
                        printf("再见了您累");
                }
        freelibrary(library);
        return 0;
}



运行之后,打印的书名和作者会乱码。并显示单链表.EXE已停止工作。麻烦帮我看看错误在哪,查了半天没看出来。

qiuyouzhi 发表于 2020-3-6 09:56:49

不要把结构体变量和结构体指针定义在函数里,要么放在main里,要么
放在结构体定义的地方

召唤师 发表于 2020-3-6 13:05:55

qiuyouzhi 发表于 2020-3-6 09:56
不要把结构体变量和结构体指针定义在函数里,要么放在main里,要么
放在结构体定义的地方

不好意思,还是不太明白?能稍微具体点吗?

qiuyouzhi 发表于 2020-3-6 13:06:52

召唤师 发表于 2020-3-6 13:05
不好意思,还是不太明白?能稍微具体点吗?

你不是在函数里写了一堆struct什么的吗?
把他们放到结构体定义的地方

召唤师 发表于 2020-3-6 13:18:17

qiuyouzhi 发表于 2020-3-6 13:06
你不是在函数里写了一堆struct什么的吗?
把他们放到结构体定义的地方

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

void addBook(struct Book **library);
void getinput(struct Book *book);
void printfbook(struct Book *library);
void freelibrary(struct Book *book);
struct Book{
        char title;
        char author;
        struct Book *next;
}*book,*temp;

void getinput(struct Book *book){
        printf("请输入书名\n");
        scanf("%s",book->title);
        printf("请输入作者\n");
        scanf("%s",book->author);
}

void addBook(struct Book **library){
        //struct Book *book,*temp;
        book=NULL;
        temp=NULL;
        book=(struct Book*)malloc(sizeof(struct Book));
        if(book==NULL){
                printf("内存分配失败了");
                exit(1);
        }
        else{
                getinput(book);
        }
        if (*library != 0)               
      {                              
                temp = *library;
                *library = book;
                book->next = temp;
      }
      else                           
      {
                *library = book;
                book->next = NULL;
      }
}

void printfbook(struct Book *library){
//        struct Book *book;
        book=library;
        int i=1;
        while(book!=NULL){
        printf("您录入的第%d本书的书名是:%s\n",i,book->title);
        printf("您录入的第%d本书的作者是:%s\n",i,book->author);       
        i++;
        book=book->next;
        }
       
}

void freelibrary(struct Book *library){
        //struct Book* temp;//temp跳出函数之后会自动释放,所以不用操心他的存在
        while(library!=NULL){
        temp=library->next;
        free(library);
        library=temp;
        }
}

int main(){
        struct Book *library=NULL;
        addBook(&library);
        char ans;


        while(1){
                printf("是否继续录入书本?Y/N\n");
                scanf("%s",&ans);
        if(ans=='Y'){
                printf("请继续录入书本信息\n");
                addBook(&library);
                    }
        else{
             break;
           }
        }
       
        printf("是否打印目录?Y/N\n");
        scanf("%s",&ans);
                if(ans=='Y'){
                        printf("开始打印书目\n");
                        printfbook(library);
                }
                else{
                        printf("再见了您勒");
                }
        freelibrary(library);
        return 0;
}

这样也不行好像。

qiuyouzhi 发表于 2020-3-6 13:28:35

召唤师 发表于 2020-3-6 13:18
#include
#include
# include


哪有把声明写在结构体定义前面的。。。
#include <stdio.h>
#include <stdlib.h>
# include <malloc.h>

struct Book{
         char title;
         char author;
         struct Book *next;
}*book,*temp;
void addBook(struct Book **library);
void getinput(struct Book *book);
void printfbook(struct Book *library);
void freelibrary(struct Book *book);

void getinput(struct Book *book){
         printf("请输入书名\n");
         scanf("%s",book->title);
         printf("请输入作者\n");
         scanf("%s",book->author);
}

void addBook(struct Book **library){
         //struct Book *book,*temp;
         book=NULL;
         temp=NULL;
         book=(struct Book*)malloc(sizeof(struct Book));
         if(book==NULL){
               printf("内存分配失败了");
               exit(1);
         }
         else{
               getinput(book);
         }
         if (*library != 0)               
         {                              
               temp = *library;
               *library = book;
               book->next = temp;
         }
         else                           
         {
               *library = book;
               book->next = NULL;
         }
}

void printfbook(struct Book *library){
//      struct Book *book;
         book=library;
         int i=1;
         while(book!=NULL){
         printf("您录入的第%d本书的书名是:%s\n",i,book->title);
         printf("您录入的第%d本书的作者是:%s\n",i,book->author);      
         i++;
         book=book->next;
         }
         
}

void freelibrary(struct Book *library){
         //struct Book* temp;//temp跳出函数之后会自动释放,所以不用操心他的存在
      while(library!=NULL){
         temp=library->next;
         free(library);
         library=temp;
         }
}

int main(){
         struct Book *library=NULL;
         addBook(&library);
         char ans;


         while(1){
               printf("是否继续录入书本?Y/N\n");
               scanf("%s",&ans);
         if(ans=='Y'){
               printf("请继续录入书本信息\n");
               addBook(&library);
                     }
         else{
            break;
            }
         }
         
         printf("是否打印目录?Y/N\n");
         scanf("%s",&ans);
               if(ans=='Y'){
                         printf("开始打印书目\n");
                         printfbook(library);
               }
               else{
                         printf("再见了您勒");
               }
         freelibrary(library);
         return 0;
}

召唤师 发表于 2020-3-6 13:58:37

qiuyouzhi 发表于 2020-3-6 13:28
哪有把声明写在结构体定义前面的。。。

你说的这个我知道了,但是还是不行……

qiuyouzhi 发表于 2020-3-6 13:59:27

召唤师 发表于 2020-3-6 13:58
你说的这个我知道了,但是还是不行……

可我这里编译过了啊

召唤师 发表于 2020-3-6 14:18:50

qiuyouzhi 发表于 2020-3-6 13:59
可我这里编译过了啊

编译完 输入两本书的内容,打印一下可以吗?我编译可以啊,运行不行啊

jzzc 发表于 2020-3-6 15:06:41

main函数换成这个,除了排版一共改了4处地方,功能应该正常{:10_282:}int main(void)
{
      struct Book *library = NULL;
      addBook(&library);
      char ans;


      while(1)
        {
                printf("是否继续录入书本?Y/N\n");
                getchar();           //加入这个回收enter键
                scanf("%c", &ans); //char类型,不是字符串,别用%s
               
              if(ans == 'Y')
                {
                              printf("请继续录入书本信息\n");
                        addBook(&library);
              }
              else
                {
                      break;
              }
      }
      
      printf("是否打印目录?Y/N\n");
      
      getchar();           //加入这个回收enter键
      scanf("%c", &ans); //一样的,char类型
      
      if(ans=='Y')
        {
                printf("开始打印书目\n");
                printfbook(library);
      }
      else
        {
              printf("再见了您累");
      }
      
      freelibrary(library);
      
      return 0;
}



召唤师 发表于 2020-3-6 15:26:10

jzzc 发表于 2020-3-6 15:06
main函数换成这个,除了排版一共改了4处地方,功能应该正常

大哥,终于可以了,没想到啊。我排查了快一天了。谢啦。为什么不用getchar会出现这样的差异?

jzzc 发表于 2020-3-6 15:32:54

召唤师 发表于 2020-3-6 15:26
大哥,终于可以了,没想到啊。我排查了快一天了。谢啦。为什么不用getchar会出现这样的差异?

导致出现exe停止应该是因为%c写成了%s,和getchar()应该没有关系,加getchar()是因为在输入完作者的信息后摁了回车,这导致scanf读取到了回车直接break了,所以加一个getchar()把这个回车给消灭掉,不让他影响我们的代码逻辑{:10_279:}

召唤师 发表于 2020-3-6 15:48:27

jzzc 发表于 2020-3-6 15:32
导致出现exe停止应该是因为%c写成了%s,和getchar()应该没有关系,加getchar()是因为在输入完作者的信息 ...

有影响,不过我明白了,谢谢!{:10_281:}{:10_281:}

jzzc 发表于 2020-3-6 15:52:09

召唤师 发表于 2020-3-6 15:48
有影响,不过我明白了,谢谢!

嗯嗯{:10_298:}
页: [1]
查看完整版本: 单链表的这个代码错误在哪?