我正在尝试打印出一个未排序的学生 ID,然后在用户输入后对其进行排序。它可以很好地打印一个空列表,但是当有实际的ID要打印时,它只是空白。为什么会这样?我只能得到一个空列表来正常工作,但不能得到一个包含任何内容的列表。
#include <stdio.h> /* printf, scanf */
#include <stdlib.h> /* malloc, exit, free */
#include <ctype.h> /* typedef, tolower */
/**********************************************************************/
/* Symbolic Constants */
/**********************************************************************/
#define MAXIMUM_ID 999999 /* Maximum student id number */
#define MINIMUM_ID 1 /* Minimum student id number */
#define LIST_HEADER MINIMUM_ID - 1
/* Header of the student id list */
#define LIST_TRAILER MAXIMUM_ID + 1
/* Trailer of the student id list */
#define HEADER_ALLOC_ERR 1 /* Error allocating the list header */
/* memory */
#define TRAILER_ALLOC_ERR 2 /* Error allocating the list */
/* trailer memory */
#define ID_ALLOC_ERR 3 /* Error allocating the student id */
/* memory */
#define QUIT 0 /* Program exit value */
/**********************************************************************/
/* Program Structures */
/**********************************************************************/
/* A school student id list */
struct student_id
{
int student_id; /* A student's id number */
struct student_id *p_next_student; /* Points to next student id */
};
typedef struct student_id ID;
/**********************************************************************/
/* Function Prototypes */
/**********************************************************************/
void print_heading();
/* Print the program heading */
void print_instructions();
/* Print the program instructions */
char get_response();
/* Get the response to continue or quit */
ID *create_empty_list();
/* Create an empty list */
void insert_student(ID *p_id_list, int student_id);
/* Insert a student at the front of the list */
void print_list(ID *p_id_list);
/* Print all the student id's in the list */
int get_count(ID *p_id_list);
/* Get the count of the students on the list */
void sort_list(ID *p_student_id);
/* Sort the students into ascending order by id */
void remove_duplicates(ID *p_id_list);
/* Remove all duplicate id's */
/**********************************************************************/
/* Main Function */
/**********************************************************************/
int main()
{
ID *p_id_list, /* Points to the student id list */
*p_next_list; /* Points to each student id in the list */
int student_id; /* A student's id number */
/* Loop processing student id list until the user says to quit */
while(print_instructions(), get_response() == 'y')
{
/* Create an empty list of student IDs */
p_id_list = create_empty_list();
/* Loop processing inserted student ids until the user says */
/* to quit */
while(printf("Enter the next student id (%d to quit): ", QUIT),
scanf ("%d", &student_id), student_id > LIST_HEADER)
{
if(student_id > MAXIMUM_ID)
{
printf(" Id rejected - it cannot exceed %d", MAXIMUM_ID);
printf("n");
}
else
insert_student(p_id_list, student_id);
}
/* Print the list of unsorted student ID's and show the number */
/* of student IDs */
printf("nThe unsorted student ID list, as entered, is: ");
print_list(p_id_list);
printf("nThe length of the unsorted student ID list is: %d",
get_count(p_id_list));
/* Print the list of sorted student ID's and show the number of */
/* student IDs */
sort_list(p_id_list);
printf("nnThe student id list, sorted ascending by id, is:");
print_list(p_id_list);
printf("nThe length of the sorted student ID list is: %d",
get_count(p_id_list));
/* Delete duplicate student IDs, print the student id list, */
/* show the number of student ids, and free the id list */
printf("n");
remove_duplicates(p_id_list);
printf("nThe student id list, with duplicate id's removed,");
printf("sorted ascending by id, is:");
print_list(p_id_list);
printf("nThe length of the cleared and sorted student");
printf("ID list is: %d", get_count(p_id_list));
while(p_id_list != NULL)
{
p_next_list = p_id_list->p_next_student;
free(p_id_list);
p_id_list = p_next_list;
}
}
/* Print a goodbye message and terminate the program */
printf("nnThanks for using this program. Have a great day! :D");
printf("nnnnnn");
return 0;
}
/**********************************************************************/
/* Print the program instructions */
/**********************************************************************/
void print_instructions()
{
printf("nnn This program maintains a list of elements by their");
printf( "n id number. After entry of all id's, it sorts them");
printf( "n into ascending order, then removes all duplicates.");
return;
}
/**********************************************************************/
/* Get the response to continue or quit */
/**********************************************************************/
char get_response()
{
char response[2]; /* Response to continue or quit */
printf("n");
do
{
printf("nDo you want to enter another student id list (y or n): ");
scanf ("%1s", &response[0]);
response[0] = tolower(response[0]);
}
while(response[0] != 'y' && response[0] != 'n');
return (response[0]);
}
/**********************************************************************/
/* Create an empty list */
/**********************************************************************/
ID *create_empty_list()
{
ID *p_new_list; /* List of student ID's */
if((p_new_list = (ID *)malloc(sizeof(ID))) == NULL)
{
printf("nnError #%d occurred in create_empty_list",
HEADER_ALLOC_ERR);
printf( "nUnable to allocate memory for the list header.");
printf( "nThe program is aborting.");
exit (HEADER_ALLOC_ERR);
}
p_new_list->student_id = LIST_HEADER;
if((p_new_list->p_next_student = (ID *)malloc(sizeof(ID))) == NULL)
{
printf("nnError #%d occurred in create_empty_list",
TRAILER_ALLOC_ERR);
printf( "nUnable to allocate memory for the list header.");
printf( "nThe program is aborting.");
exit (TRAILER_ALLOC_ERR);
}
p_new_list->p_next_student->student_id = LIST_TRAILER;
p_new_list->p_next_student->p_next_student = NULL;
return p_new_list;
}
/**********************************************************************/
/* Insert a student at the front of the list */
/**********************************************************************/
void insert_student(ID *p_id_list, int insert_id)
{
ID *p_current_id = p_id_list->p_next_student,
*p_new_list, /* Points to the new id list */
*p_previous_id = p_id_list;
while(
if((p_new_list = (ID *)malloc(sizeof(ID))) == NULL)
{
printf("nnError #%d occurred in insert_student", ID_ALLOC_ERR);
printf( "nUnable to allocate memory for a new student id.");
printf( "nThe program is aborting.");
exit (ID_ALLOC_ERR);
}
p_new_list->student_id = insert_id;
p_new_list->p_next_student = p_current_id;
p_previous_id->p_next_student = p_new_list;
return;
}
/**********************************************************************/
/* Print all the student id's in the list */
/**********************************************************************/
void print_list(ID *p_id_list)
{
printf("nEntering print_list");
if(get_count(p_id_list) == LIST_HEADER)
printf("n The student id list is empty.");
else
{
while(p_id_list = p_id_list->p_next_student,
p_id_list->student_id < LIST_TRAILER)
{
printf("nEntering loop");
printf("n %6d", p_id_list->student_id);
}
}
return;
}
/**********************************************************************/
/* Get the count of the students on the list */
/**********************************************************************/
int get_count(ID *p_id_list)
{
int student_count=0; /* Counts the length of the id list */
while(p_id_list->p_next_student->student_id != LIST_TRAILER)
student_count += 1;
return(student_count);
}
/**********************************************************************/
/* Sort the students into ascending order by id */
/**********************************************************************/
void sort_list(ID *p_student_id)
{
ID *p_id_list, /* Pointer to a student ID */
*p_temp_id; /* Pointer to a temporary student ID */
int student_number; /* Student ID sorting counter */
for (student_number = 0; student_number < get_count(p_student_id);
student_number++)
{
p_id_list = p_student_id;
while(p_id_list->p_next_student->p_next_student->student_id !=
LIST_TRAILER)
{
if(p_id_list->p_next_student->student_id <
p_id_list->p_next_student->p_next_student->student_id)
{
p_temp_id =
p_id_list->p_next_student->p_next_student;
p_id_list->p_next_student->p_next_student
= p_temp_id->p_next_student;
p_temp_id->p_next_student = p_id_list->p_next_student;
p_id_list->p_next_student = p_temp_id;
}
p_student_id = p_student_id->p_next_student;
}
}
}
/**********************************************************************/
/* Remove all duplicate id's */
/**********************************************************************/
void remove_duplicates(ID *p_id_list)
{
ID *p_current_id = p_id_list->p_next_student,
/* Points to the current id */
*p_previous_id = p_id_list; /* Points to the previous id */
printf("n");
while(p_current_id->student_id != LIST_TRAILER)
{
if(p_previous_id->student_id == p_current_id->student_id)
{
printf("nDeleting the duplicate student id: %d",
p_current_id->student_id);
p_previous_id->p_next_student = p_current_id->p_next_student;
free(p_current_id);
p_current_id = p_previous_id->p_next_student;
}
else
{
p_previous_id = p_previous_id->p_next_student;
p_current_id = p_current_id->p_next_student;
}
}
return;
}
我不确定哪个功能是问题所在,因为它对我来说很好。
在get_count
中有一个infinete循环,因为它一遍又一遍地检查相同的p_id_list
,而不会移动到下一条记录。
while(p_id_list->p_next_student->student_id != LIST_TRAILER)
student_count += 1;
只需要确保在每个循环中访问下一条记录。例如:
ID *cur = p_id_list->p_next_student;
while (cur->student_id != LIST_TRAILER) {
student_count += 1;
cur = cur->p_next_student;
}