在(C)中扫描新节点时按字母顺序排序链表

在(C)中扫描新节点时按字母顺序排序链表,c,pointers,struct,linked-list,singly-linked-list,C,Pointers,Struct,Linked List,Singly Linked List,我已经连续一周在做这个项目了,今晚午夜到期。我是一名计算机科学的大一学生,对编程一无所知,所以我看不出这段代码有什么问题。代码应该将事件标题、事件时间和事件日期读入一个链接列表,并使用事件标题按字母顺序排序 这是来自文件的输入: Birthday 12 30 10 01 2018 Wedding 06 30 06 15 2018 Seminar 05 00 02 15 2019 Birthday 04 00 06 15 2018 Anniversary 08 30 12 09 2019 生日 1

我已经连续一周在做这个项目了,今晚午夜到期。我是一名计算机科学的大一学生,对编程一无所知,所以我看不出这段代码有什么问题。代码应该将事件标题、事件时间和事件日期读入一个链接列表,并使用事件标题按字母顺序排序

这是来自文件的输入:

Birthday 12 30 10 01 2018 Wedding 06 30 06 15 2018 Seminar 05 00 02 15 2019 Birthday 04 00 06 15 2018 Anniversary 08 30 12 09 2019 生日 12 30 10 01 2018 婚礼 06 30 06 15 2018 研讨会 05 00 02 15 2019 生日 04 00 06 15 2018 周年纪念 08 30 12 09 2019 由于某些原因,它从不将婚礼事件连接到链接列表,而且在打印整个链接列表时,会有一个空白节点作为头节点。我一直在做这件事,即使在跟踪代码的时候,我也无法找出哪里出了问题

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

//struct for event time
typedef struct{

  int hour;
  int minute;

} event_time_t;

//struct for event date
typedef struct{

  int month;
  int day;
  int year;

} event_date_t;

//struct for all event info
struct event{

  char event_title[20];
  event_time_t event_time;
  event_date_t event_date;
  struct event *next;

};

typedef struct event event_t;

void add_events (event_t **head_ptr);
void print_event(event_t *head_ptr);
void print_slected_event (event_t *head_ptr, int month, int day, int year);

int main () {

  event_t *head_ptr = malloc(sizeof(event_t));

  add_events(&head_ptr);

  print_event(head_ptr);

  print_slected_event(head_ptr,6,15,2018);

  return 0;
}

void add_events (event_t **head_ptr){

  event_t *temp;
  event_t *temp_head = *head_ptr;
  event_t *new_node;

  scanf(" %s",temp_head->event_title);
  scanf("%d",&temp_head->event_time.hour);
  scanf("%d",&temp_head->event_time.minute);
  scanf("%d",&temp_head->event_date.month);
  scanf("%d",&temp_head->event_date.day);
  scanf("%d",&temp_head->event_date.year);
  temp_head->next = NULL;

  while(!feof(stdin)){

    new_node = malloc(sizeof(event_t));

    scanf(" %s",new_node->event_title);
    scanf("%d",&new_node->event_time.hour);
    scanf("%d",&new_node->event_time.minute);
    scanf("%d",&new_node->event_date.month);
    scanf("%d",&new_node->event_date.day);
    scanf("%d",&new_node->event_date.year);



    if(temp_head->next == NULL){

      temp_head->next = new_node;

    }

    else if(strcmp(temp_head->event_title,new_node->event_title)>0){

      new_node->next = temp_head;
      temp_head = new_node;
      *head_ptr = temp_head;

    }

    else{

      temp = temp_head;

      while(temp->next!=NULL){

        if(strcmp(temp->event_title,new_node->event_title)==0){

          break;
        }
        if(strcmp(temp->event_title,new_node->event_title)<0){

          break;

        }

        temp = temp->next;
      }


        new_node->next = temp->next;
        temp->next = new_node;


    }


  }

}

void print_event(event_t *head_ptr){

  event_t *temp;
  temp = malloc(sizeof(event_t));
  temp = head_ptr;

  printf("Scedule of Events:\n");
  while(temp->next!=NULL){

    printf("\t%-13s at: %02d:%02d ",temp->event_title,temp->event_time.hour,temp->event_time.minute);
    printf("on: %02d/%02d/%d\n",temp->event_date.month,temp->event_date.day,temp->event_date.year);

    temp = temp->next;
  }
}

void print_slected_event (event_t *head_ptr, int month, int day, int year){

  event_t *temp;
  temp = malloc(sizeof(event_t));
  temp = head_ptr;

  printf("Date: %02d/%02d/%d\n",month,day,year);
  printf("Events:\n");
  while(temp->next!=NULL){

    if(temp->event_date.month == month){
      if(temp->event_date.day == day){
        if(temp->event_date.year == year){

          printf("\t%-13s at: %02d:%02d\n",temp->event_title,temp->event_time.hour,temp->event_time.minute);

        }
      }
    }

    temp = temp->next;
  }
}
#包括
#包括
#包括
//事件时间结构
类型定义结构{
整小时;
整数分钟;
}事件时间;
//事件日期的结构
类型定义结构{
整月;
国际日;
国际年;
}事件日期;
//所有事件信息的结构
结构事件{
char事件_标题[20];
事件时间t事件时间;
事件日期事件日期;
结构事件*下一步;
};
类型定义结构事件;
作废添加事件(事件**标题ptr);
无效打印事件(事件*头ptr);
作废打印所选事件(事件*头事件、整数月、整数日、整数年);
int main(){
事件头=malloc(事件大小);
添加事件(&head\U ptr);
打印事件(打印头ptr);
打印所选事件(标题ptr,6,152018);
返回0;
}
作废添加事件(事件**头ptr){
事件温度;
事件*温度*头部=*头部ptr;
事件*新节点;
扫描(“%s”,临时标题->事件标题);
scanf(“%d”,&temp\u head->event\u time.hour);
scanf(“%d”,&temp\u head->event\u time.minute);
scanf(“%d”、&temp\u head->event\u date.month);
scanf(“%d”、&temp\u head->event\u date.day);
scanf(“%d”、&temp\u head->event\u date.year);
温度头->下一步=空;
而(!feof(stdin)){
新节点=malloc(sizeof(event_t));
scanf(“%s”,新节点->事件标题);
scanf(“%d”,&新建节点->事件时间.hour);
scanf(“%d”,&new\u node->event\u time.minute);
scanf(“%d”,&new\u节点->event\u date.month);
scanf(“%d”,&new\u node->event\u date.day);
scanf(“%d”和新节点->事件日期.year);
如果(临时头->下一步==NULL){
临时头->下一步=新节点;
}
else if(strcmp(临时标题->事件标题,新节点->事件标题)>0){
新建节点->下一步=临时头;
临时头=新节点;
*压头ptr=温度压头;
}
否则{
温度=温度头;
while(临时->下一步!=NULL){
if(strcmp(临时->事件标题,新节点->事件标题)==0){
打破
}
if(strcmp(临时->事件标题,新节点->事件标题)下一步;
}
新建节点->下一步=临时->下一步;
temp->next=新节点;
}
}
}
无效打印事件(事件*打印头){
事件温度;
temp=malloc(sizeof(event_t));
温度=压头温度;
printf(“事件日程:\n”);
while(临时->下一步!=NULL){
printf(“\t%-13s在:%02d:%02d”,temp->event\u title,temp->event\u time.hour,temp->event\u time.minute);
printf(“日期:%02d/%02d/%d\n”,临时->事件日期.月,临时->事件日期.日,临时->事件日期.年);
温度=温度->下一步;
}
}
无效打印所选事件(事件头事件、整数月、整数日、整数年){
事件温度;
temp=malloc(sizeof(event_t));
温度=压头温度;
printf(“日期:%02d/%02d/%d\n”,月、日、年);
printf(“事件:\n”);
while(临时->下一步!=NULL){
如果(临时->事件\日期.月份==月份){
如果(临时->事件\日期.day==天){
如果(临时->事件\日期.年==年){
printf(“\t%-13s在:%02d:%02d\n”,temp->event\u title,temp->event\u time.hour,temp->event\u time.minute);
}
}
}
温度=温度->下一步;
}
}

在列表中插入节点的函数应与从文件中读取数据或用数据填充结构的代码分开

我可以提出以下方法

//struct for event time
typedef struct{

  int hour;
  int minute;

} event_time_t;

//struct for event date
typedef struct{

  int month;
  int day;
  int year;

} event_date_t;

//struct for all event info
typedef struct{
  char event_title[20];
  event_time_t event_time;
  event_date_t event_date;
} event_t;

//struct for node of the list
typedef struct node
{
    event_t event;
    struct node *next;
} node_t;

//struct for the list itself
typedef struct
{
    node_t *head;
} list_t;
在这种情况下,在列表中插入节点的函数可以如下所示

int add_event( list_t *list, event_t *event )
{
    node_t **current = &list->head;

    while ( *current != NULL && !( strcmp( event->event_title, ( *current )->event.event_title ) < 0 ) )
    {
        current = &( *current )->next;
    }

    node_t *new_node = malloc( sizeof( node_t ) );
    int success = new_node != NULL;

    if ( success )
    {
        new_node->event = *event;
        new_node->next = *current;

        *current = new_node;
    }

    return success;
}
当您可以编写从文件读取数据的函数时,填充结构事件并调用函数
add_event
传递指向列表的指针和指向填充结构的指针

这是一个简化的演示程序

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

//struct for event time
typedef struct{

  int hour;
  int minute;

} event_time_t;

//struct for event date
typedef struct{

  int month;
  int day;
  int year;

} event_date_t;

//struct for all event info
typedef struct{
  char event_title[20];
  event_time_t event_time;
  event_date_t event_date;
} event_t;

//struct for node of the list
typedef struct node
{
    event_t event;
    struct node *next;
} node_t;

//struct for the list itself
typedef struct
{
    node_t *head;
} list_t;

int add_event( list_t *list, event_t *event )
{
    node_t **current = &list->head;

    while ( *current != NULL && !( strcmp( event->event_title, ( *current )->event.event_title ) < 0 ) )
    {
        current = &( *current )->next;
    }

    node_t *new_node = malloc( sizeof( node_t ) );
    int success = new_node != NULL;

    if ( success )
    {
        new_node->event = *event;
        new_node->next = *current;

        *current = new_node;
    }

    return success;
}

void print_list( const list_t *list )
{
    for ( const node_t *current = list->head; current != NULL; current = current->next )
    {
        printf( "%s -> ", current->event.event_title );
    }
    puts( "null" );
}

int main(void) 
{
    list_t list = { .head = NULL };

    event_t event = { "third", { 0 }, { 0 } };

    add_event( &list, &event );

    print_list( &list );

    strcpy( event.event_title, "first" );

    add_event( &list, &event );

    print_list( &list );

    strcpy( event.event_title, "second" );

    add_event( &list, &event );

    print_list( &list );

    return 0;
}

这是开发项目的起点。

Fyi.。最好现在就知道,而不是以后。没有任何实际IO读取被验证,这是一个巨大的错误。我的建议是一个大的重新设计。与其使用一个读取数据的函数,不如插入列表,然后对列表排序,将其拆分为多个较小的函数责任有限的ons。遵循和原则。因此,一个函数从文件中读取一条记录,一个函数向列表中插入数据,还有一个函数对列表进行排序。仅供参考,您的
print
函数都不应进行任何分配。这两个函数的前三行都立即停止ak内存(准确地说是第二行和第三行)。打印时,不应测试
temp->next
是否为空,而应测试
temp
。这会使您错过婚礼活动。(打印和插入的不同之处在于,打印只需要查看当前节点,而插入必须查看两个连续节点,这样才能更新它们的链接。)@WhozCraig好的,我读了几篇文章,想知道为什么
!feof(stdin)
总是错误的,这很有道理,所以我在(scanf(“%s”,新节点->事件标题)==1)它去掉了那个随机的空头节点。我还去掉了将内存分配给临时节点的打印函数。@M哦,这更有意义,当我更改它时,它立即开始打印婚礼事件。非常感谢你们,自从取消课程以来,链表一直很难,但我有一个更好的方法因为读了你的建议,我现在站起来了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//struct for event time
typedef struct{

  int hour;
  int minute;

} event_time_t;

//struct for event date
typedef struct{

  int month;
  int day;
  int year;

} event_date_t;

//struct for all event info
typedef struct{
  char event_title[20];
  event_time_t event_time;
  event_date_t event_date;
} event_t;

//struct for node of the list
typedef struct node
{
    event_t event;
    struct node *next;
} node_t;

//struct for the list itself
typedef struct
{
    node_t *head;
} list_t;

int add_event( list_t *list, event_t *event )
{
    node_t **current = &list->head;

    while ( *current != NULL && !( strcmp( event->event_title, ( *current )->event.event_title ) < 0 ) )
    {
        current = &( *current )->next;
    }

    node_t *new_node = malloc( sizeof( node_t ) );
    int success = new_node != NULL;

    if ( success )
    {
        new_node->event = *event;
        new_node->next = *current;

        *current = new_node;
    }

    return success;
}

void print_list( const list_t *list )
{
    for ( const node_t *current = list->head; current != NULL; current = current->next )
    {
        printf( "%s -> ", current->event.event_title );
    }
    puts( "null" );
}

int main(void) 
{
    list_t list = { .head = NULL };

    event_t event = { "third", { 0 }, { 0 } };

    add_event( &list, &event );

    print_list( &list );

    strcpy( event.event_title, "first" );

    add_event( &list, &event );

    print_list( &list );

    strcpy( event.event_title, "second" );

    add_event( &list, &event );

    print_list( &list );

    return 0;
}
third -> null
first -> third -> null
first -> second -> third -> null