嘿,伙计们,我正在做一个项目,我不断收到“库为空”,然后出现段错误,通过 gdb 运行它告诉我错误在我的 count_list 函数中。但我似乎无法弄清楚为什么?任何提示将不胜感激,因为它让我如此接近完成并挂断了电话。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Assume max char count in file */
#define MAX 20
/* library struct - DO NOT CHANGE */
typedef struct library
{
char *genre;
char *band;
char *album;
float rating;
struct library *next;
}Library;
/* Function Prototypes - DO NOT CHANGE */
Library *Read_File(FILE *);
void Print(Library *);
Library *Create_List(Library *, Library *);
Library *Create_Album(char *, char *, char *, float);
Library *Merge(Library *, Library *);
int Count_List(Library *);
void Split_List(Library *, Library **, Library **);
Library *Merge_Sort(Library *);
Library *Delete_Genre(Library *);
void Free_Entry(Library *);
Library *Clean(Library *);
/* MAIN
* Error check file parameter
* Call Read_File to fill our list
* Print our list
* Merge Sort the linked list (by genre)
* Delete a genre
* Free the list
*/
int
main(int argc, char **argv)
{
if(argc != 2)
{
printf("Not enough arguments.\n");
return 0;
}
FILE *fp = NULL;
if((fp = fopen(argv[1], "r")) == NULL)
{
printf("File can not be opened.\n");
return 0;
}
Library *Head = NULL;
Head = Read_File(fp);
Print(Head);
Merge_Sort(Head);
Print(Head);
Head = Delete_Genre(Head);
Print(Head);
Head = Clean(Head);
Print(Head);
return 0;
}
/* Clean()
* Delete the linked list, recursively
*/
Library *
Clean(Library *Head)
{
if(Head) return NULL;
Library *Tmp = Head->next;
Free_Entry(Head);
Clean(Tmp->next);
}
/* Free_Entry()
* wrapper function to free a struct Library
*/
void
Free_Entry(Library *Entry)
{
free(Entry);
}
/* Delete_Genre()
* Deletes a genre inputted by user
* Logic:
* prompt user for genre input
* traverse list deleting all structs that contain the genre
*/
Library *
Delete_Genre(Library *Head)
{
if(!Head)
{
printf("List Empty.\n");
return NULL;
}
char *input = malloc(MAX * sizeof(char *));
Library *Current = Head;
Library *Tail = NULL;
printf("Which genre would you like to delete?\n");
scanf("%s", input);
while(Current)
{
if(strcmp(Current->genre, input))
{
if(Current = Head)
{
Head = Head->next;
Free_Entry(Current);
Current = Head;
}
else
Tail->next = Current->next;
}
else
Current = Current->next;
}
}
/* Read_File()
* Open file fp
* Create a struct from information in text file
* Link our list with newly created struct
*/
Library *
Read_File(FILE *fp)
{
Library *Head, *Entry;
Head = Entry = NULL;
char *genre, *band, *album;
float rating;
while(1)
{
fscanf(fp, "%s %s %s %f", &genre, &band, &album, &rating);
if(!feof(fp))
break;
Entry = Create_Album(genre, band, album, rating);
Head = Create_List(Entry, Head);
}
return Head;
}
/* Print()
* Print the linked list
*/
void
Print(Library *Head)
{
if(!Head)
{
printf("Library is empty.\n");
return;
}
while(Head)
{
printf("%20s %20s %20s %20.2f \n",
Head->genre, Head->band, Head->album, Head->rating);
Head = Head->next;
}
printf("\n\n");
//return Head;
}
/* Create_Album
* Create a struct and assign the given args to it as appropriate
*/
Library *
Create_Album(char *genre, char *band, char *album, float rating)
{
Library *Entry = malloc(sizeof(Library));
strcpy(Entry->genre, genre);
strcpy(Entry->band, band);
strcpy(Entry->album, album);
Entry->rating = rating;
Entry->next = NULL;
return Entry;
}
/* Create_List()
* Push Entry onto our List
*/
Library *
Create_List(Library *Head, Library *Entry)
{
if(!Head)
return Entry;
Entry->next = Head;
return Entry;
}
/* Merge_Sort()
* Recursively split our list between Left and Right
* Merge our Left and Right lists
*/
Library *
Merge_Sort(Library *Head)
{
Library *Tmp = Head;
Library *Left, *Right, *Result;
Left = Right = Result = NULL;
int count = Count_List(Head);
if(count = 1)
return Tmp;
Left = Merge_Sort(Left);
Right = Merge_Sort(Right);
Result = Merge(Left, Right);
return Result;
}
/* Split_List()
* split our list in half
*/
void
Split_List(Library *Head, Library **Left, Library **Right)
{
int size = Count_List(Head);
int i;
Library *Tmp = Head;
*Left = Head;
for(i=1; i<size/2; ++i)
Tmp=Tmp->next;
*Right = Tmp->next;
Tmp->next = NULL;
}
/* Merge()
* Merge two linked lists Left and Right together in sorted order
*/
Library *
Merge(Library *Left, Library *Right)
{
Library *Result, *Tmp;
Result = Tmp = NULL;
if(strcmp(Left->genre, Right->genre) <= 0)
{
Result = Left;
Left = Left->next;
}
else
{
Result = Right;
Right = Right->next;
}
Tmp = Result;
while(Left != NULL && Right != NULL)
{
if(Left != NULL && Right!= NULL)
{
if (strcmp(Left->genre, Right->genre) <= 0)
{
Tmp->next = Left;
Left = Left->next;
}
else
{
Tmp->next = Right;
Right = Right->next;
}
Tmp = Tmp->next;
}
}
return Result;
}
/* Count_List()
* Count the number of elements in a linked list
*/
int
Count_List(Library *Head)
{
Library *Tmp = Head;
int count = 0;
while(Tmp->next != NULL)
{
count++;
Tmp = Tmp->next;
}
}