我的打印链接列表的功能没有打印它

问题描述 投票:0回答:1

我有一个代码,我正在尝试做一些歌曲的播放列表。它们将位于通过链接列表连接的结构上,其中包含歌曲名称和时间。 在程序中,有一个执行命令的函数(可以在开始/结束时添加、删除或播放)。当执行 play 命令时,它应该调用函数 print_list,但显然它没有被调用,并且列表也没有被打印。

我尝试在 main 函数中写入 print_list 的内容,检查 PLAY 是否获取其值 2,以便execute_cmd 正确调用 print_lists。尽管如此,它并没有打印链接列表的内容。

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

typedef enum commands { ADDBEG, ADDEND, PLAY, REMOVE, INVALID } command_t;

typedef struct song_s {
  char name[99];
  char time[20];
  struct song_s *next;
} song_t;

void insert_end(song_t **p, song_t *entry);
void insert_begin(song_t **p, song_t *entry);
void remove_song(song_t **p, song_t *entry);
void execute_cmd(command_t command, song_t **head, song_t *entry);
bool already_present(song_t **p, song_t *new_song);
void print_list(song_t *p);

command_t split_input(char *input, song_t *song) {
  command_t command = INVALID;
  int len = strlen(input);

  // Remove the newline character, if present
  if (input[len - 1] == '\n') {
    input[len - 1] = '\0';
  }

  // Check if the input command is "PLAY"
  if (strcmp(input, "PLAY") == 0) {
    return PLAY;
  }

  char *token = strtok(input, ",");
  char *data[3];
  int i = 0;

  // Check if the input command starts with "REMOVE,"
  if (input[0] == 'R') {
    while (token != NULL && i < 2) {
      data[i] = token;
      token = strtok(NULL, ",");
      printf("%s", data[i]);
      i++;
    }
    return REMOVE;
  }

  // Check if the input command starts with "ADDBEG" or "ADDEND"
  if (input[0] == 'A') {
    while (token != NULL && i < 3) {
      data[i] = token;
      printf("%s\n", token);
      token = strtok(NULL, ",");
      i++;
    }
  }

  // Set the command based on the input data
  if (strcmp(data[0], "ADDBEG") == 0) {
    command = ADDBEG;
  } else if (strcmp(data[0], "ADDEND") == 0) {
    command = ADDEND;
  }

  // Copy song data if available
  if (data[1] != NULL)
    strcpy(song->name, data[1]);
  if (data[2] != NULL)
    strcpy(song->time, data[2]);

  return command;
}

int main(void) {
  char input[100];
  song_t song;
  song_t *head = NULL;
  int total_time = 0;
  command_t command;

  while (1) {
    printf("input: ");
    fgets(input, 100, stdin);
    command = split_input(input, &song);
    if (command == PLAY) {
      printf("total time: %d\n", total_time);
      break;
    }
    // Total time calculation
    if (command == ADDBEG || command == ADDEND) {
      if (!already_present(&head, &song)){
          total_time += atoi(song.time);
      }
    } 
    if (command == REMOVE) {
      total_time -= atoi(song.time);
    }
    // Execution based on command
    execute_cmd(command, &head, &song);
  }
  return 0;
}

void insert_end(song_t **p, song_t *entry) {
  song_t *q = (song_t *)malloc(sizeof(song_t));
  memcpy(q, entry, sizeof(song_t));
  q->next = NULL;
  song_t *aux;
  if (*p == NULL)
    *p = q;
  else {
    aux = *p;
    while (aux->next != NULL)
      aux = aux->next;
    aux->next = q;
  }
}

void insert_begin(song_t **p, song_t *entry) {
  song_t *q = (song_t *)malloc(sizeof(song_t));
  memcpy(q, entry, sizeof(song_t));
  q->next = *p;
  *p = q;
}

void remove_song(song_t **p, song_t *entry) {
  song_t *q = *p;
  if (q == NULL)
    return;  // empty list
  if (strcmp(q->name, entry->name) == 0) {
    *p = q->next;
    free(q);
    return;
  }
  while (q->next != NULL) {
    if (strcmp(q->next->name, entry->name) == 0)
      break;
    q = q->next;
  }
  if (q->next == NULL)
    return; // value not found
  song_t *tmp = q->next;
  q->next = tmp->next;
  free(tmp);
}

void print_list(song_t *p) {
  while (p != NULL) {
    printf("Song Name: %s, Time: %s\n", p->name, p->time);
    p = p->next;
  }
}

void execute_cmd(command_t command, song_t **head, song_t *new_song) {
  // Call the appropriate function based on the command
  if (command == ADDBEG) {
    insert_begin(head, new_song);
  } else if (command == ADDEND) {
    insert_end(head, new_song);
  } else if (command == REMOVE) {
    remove_song(head, new_song);
  } else if (command == PLAY) {
    print_list(*head);
  } else {
    printf("Invalid command\n");
  }
}

// Check if the song is already in the playlist
bool already_present(song_t **p, song_t *new_song) {
    song_t *q = *p;
    while (q != NULL) {
      if (strcmp(q->name, new_song->name) == 0) {
        return true;
      }
      q = q->next;
    }
    return false;
}

c data-structures linked-list
1个回答
0
投票
  1. split_input()
    对我而言,输入=“10”时出现段错误,因为
    song
    data
    均未初始化,如果它们不指向字符串,则对
    strcmp()
    的调用是未定义的行为。

  2. split_input()
    printf("%s\n", token)
    上的段错误 如果
    input[0] == 'A'
    并且该行的其余部分不包含 2 个逗号,或者如果 `input[0] == 'R' 并且留置权的其余部分不包含逗号。

  3. main()
    中断将终止
    while
    循环,因此
    execute_cmd()
    永远不会运行:

        if (command == PLAY) {
            printf("total time: %d\n", total_time);
            break;
        }

这是修改后的程序:

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

typedef enum commands { ADDBEG, ADDEND, PLAY, REMOVE, INVALID } command_t;

typedef struct song_s {
    char name[99];
    char time[20];
    struct song_s *next;
} song_t;

void insert_end(song_t **p, song_t *entry);
void insert_begin(song_t **p, song_t *entry);
void remove_song(song_t **p, song_t *entry);
void execute_cmd(command_t command, song_t **head, song_t *entry);
bool already_present(song_t **p, song_t *new_song);
void print_list(song_t *p);

command_t split_input(char *input, song_t *song) {
    command_t command = INVALID;
    int len = strlen(input);

    if (input[len - 1] == '\n') {
        input[len - 1] = '\0';
    }

    if (!strcmp(input, "PLAY")) {
        return PLAY;
    }

    char *token = strtok(input, ",");
    char *data[3];

    if (input[0] == 'A') {
        for(int i = 0; token && i < 3; i++) {
            data[i] = token;
            token = strtok(NULL, ",");
        }
    }
    if (input[0] == 'R') {
        for(int i = 0; token && i < 2; i++) {
            data[i] = token;
            token = strtok(NULL, ",");
        }
        return REMOVE;
    }

    if (!strcmp(data[0], "ADDBEG")) {
        command = ADDBEG;
    } else if (!strcmp(data[0], "ADDEND")) {
        command = ADDEND;
    }

    if (data[1]) strcpy(song->name, data[1]);
    if (data[2]) strcpy(song->time, data[2]);

    return command;
}

int main(void) {
    char input[100];
    song_t *head = NULL;
    int total_time = 0;
    command_t command;

    while (1) {
        printf("input: ");
        fgets(input, 100, stdin);
        song_t song = {0};
        command = split_input(input, &song);
        if (command == PLAY)
            printf("total time: %d\n", total_time);
        else if (command == ADDBEG || command == ADDEND) {
            if (!already_present(&head, &song)){
                total_time += atoi(song.time);
            }
        }
        else if (command == REMOVE) {
            total_time -= atoi(song.time);
        }
        execute_cmd(command, &head, &song);
    }
    return 0;
}

void insert_end(song_t **p, song_t *entry) {
    song_t *q = malloc(sizeof(song_t));
    memcpy(q, entry, sizeof(song_t));
    q->next = NULL;
    song_t *aux;
    if (*p == NULL)
        *p = q;
    else {
        aux = *p;
        while (aux->next != NULL)
            aux = aux->next;
        aux->next = q;
    }
}

void insert_begin(song_t **p, song_t *entry) {
    song_t *q = malloc(sizeof *q);
    memcpy(q, entry, sizeof *q);
    q->next = *p;
    *p = q;
}

void remove_song(song_t **p, song_t *entry) {
    song_t *q = *p;
    if (!q)
        return;  // empty list
    if (strcmp(q->name, entry->name) == 0) {
        *p = q->next;
        free(q);
        return;
    }
    while (q->next) {
        if (strcmp(q->next->name, entry->name) == 0)
            break;
        q = q->next;
    }
    if (!q->next)
        return; // value not found
    song_t *tmp = q->next;
    q->next = tmp->next;
    free(tmp);
}

void print_list(song_t *p) {
    while (p != NULL) {
        printf("Song Name: %s, Time: %s\n", p->name, p->time);
        p = p->next;
    }
}

void execute_cmd(command_t command, song_t **head, song_t *new_song) {
    if (command == ADDBEG) {
        insert_begin(head, new_song);
    } else if (command == ADDEND) {
        insert_end(head, new_song);
    } else if (command == REMOVE) {
        remove_song(head, new_song);
    } else if (command == PLAY) {
        print_list(*head);
    } else {
        printf("Invalid command\n");
    }
}

// Check if the song is already in the playlist
bool already_present(song_t **p, song_t *new_song) {
    song_t *q = *p;
    while (q != NULL) {
        if (!strcmp(q->name, new_song->name))
            return true;
        q = q->next;
    }
    return false;
}

和示例会话:

input: ADDBEG,a,1
input: PLAY     
total time: 1
Song Name: a, Time: 1
input:

ctrl-c 将终止程序,或者您可以添加退出命令。

© www.soinside.com 2019 - 2024. All rights reserved.