1. add_artist
Artist* create_artist_instance(char* name) // Artist 객체를 생성하는 함수
{
Artist* ptr_artist = (Artist*)malloc(sizeof(Artist));
ptr_artist->name = name;
ptr_artist->head = NULL;
ptr_artist->tail = NULL;
ptr_artist->next = NULL;
return ptr_artist;
}
Artist* add_artist(char* name)
{
// Artist 객체를 만드는 일을 함수에게 맡김
Artist* ptr_artist = create_artist_instance(name);
Artist* p = artist_directory[(unsigned char)name[0]]; // 새롭게 만들 연결리스트의 첫 번째(배열의 이름)
Artist* q = NULL; // 연결 리스트에서 p를 따라가며 위치를 기억하는 용도
while (p != NULL && strcmp(p->name, name) < 0) // ordered list에서 p보다 작은 값이 나타날 때 까지
{
q = p;
p = p->next;
}
if (p == NULL && q == NULL) // 리스트가 비어있을 때. 즉 p가 유일한 노드가 됨
{
artist_directory[(unsigned char)name[0]] == ptr_artist;
}
else if (q == NULL) // p가 맨 앞에 위치할 때
{
ptr_artist->next = artist_directory[(unsigned char)name[0]];
artist_directory[(unsigned char)name[0]] = ptr_artist;
}
else // 리스트의 중간에 추가될 때
{
ptr_artist->next = p;
q->next = ptr_artist;
}
return ptr_artist;
}
2. add_song
void insert_node(Artist* ptr_artist, SNode* ptr_snode)
{
SNode* p = ptr_artist->head;
// head에 저장된 값보다 ptr_snode에 저장된 제목이 클 때까지 while문 반복
while (p != NULL && strcmp(p->song->title, ptr_snode->song->title)<0)
p = p->next;
// p가 ptr_snode가 들어갈 자리보다 한 자리 뒤에 있기 때문에 p의 앞 위치에 새로운 snode를 대입
// 1. 연결리스트가 비어있을 때 2. 맨 앞에 대입할 때 3. 맨 뒤에 대입할 때 4. 노래 사이에 대입
if (ptr_artist->head == NULL) { // 1번 케이스
ptr_artist->head = ptr_snode;
ptr_artist->tail = ptr_snode; // 리스트의 유일한 곡이기 때문에 이중연결리스트의 head와 tail이 모두 ptr_snode
}
else if (p == ptr_artist->head) { // 2번 케이스.
ptr_snode->next = ptr_artist->head;
ptr_artist->head->prev = ptr_snode;
ptr_artist->head = ptr_snode; // 새로운 곡이 곡 리스트의 첫 번째 곡 자리에 위치함
}
else if(p==NULL){ // 3번 케이스.
ptr_snode->prev = ptr_artist->tail;
ptr_artist->tail->next = ptr_snode;
ptr_artist->tail = ptr_snode;
}
else { // 4번 케이스. p 앞에 노래를 추가
ptr_snode->next = p;
ptr_snode->prev = p->prev;
p->prev->next = ptr_snode;
p->prev = ptr_snode;
}
}
void add_song(char* artist, char* title, char* path)
{
// 가수가 이미 존재하는 경우
// 존재하지 않는다면 NULL return
Artist* ptr_artist = find_artist(artist); // 가수를 찾아서 Artist 포인터를 return
if (ptr_artist == NULL) // 만약 가수가 플레이리스트에 존재하지 않는다면
{
ptr_artist = add_artist(artist); // artist라는 이름을 가진 Artist 객체를 하나 추가하여 그 주소를 리턴
}
Song* ptr_song = create_song_instance(ptr_artist, title, path);
SNode* ptr_snode = (SNode*)malloc(sizeof(SNode));
ptr_snode->song = ptr_song; // SNode들끼리 이중연결리스트로 연결되는 구조.
ptr_snode->next = NULL; // 의도치 않은 실수를 방지하기 위해 구조체의 포인터 값은 null로 설정해주는 것도 좋음
// insert node
insert_node(ptr_artist, ptr_snode);
}
3. status를 통해 상태 확인
void status()
{
for (int i = 0; i < NUM_CHARS; i++)
{
Artist* p = artist_directory[i]; //
while (p!=NULL)
{
print_artist(p);
p = p->next;
}
}
}
void print_artist(Artist* p)
{
printf("name: %s\n", p->name);
SNode* ptr_snode = p->head;
while (ptr_snode != NULL)
{
print_song(ptr_snode->song);
ptr_snode = ptr_snode->next;
}
}
void print_song(Song* ptr_song)
{
printf("%d: %s, %s\n", ptr_song->index, ptr_song->title, ptr_song->path);
}
4. load file
1) main.cpp
int main()
{
initialize(); // Artist 배열을 초기화
handle_load(); // process_command() 이전에 미리 파일을 로드할 것인지 물어봄
process_command();
}
2. library.cpp
void load(FILE* fp)
{
char buffer[BUFFER_LENGTH];
char* name, * title, * path;
while (1)
{
if (read_line(fp, buffer, BUFFER_LENGTH) <= 0) // fp에 저장한 입력 스트림으로부터 데이터를 읽음
break;
name = strtok(buffer, "#"); // 공백문자 전까지 tokenize하여 저장
if (strcmp(name, " ") == 0) // 이름이 존재하지 않는다면
name = NULL;
else
name = strdup(name); // 이름을 복제하여 저장
title = strtok(NULL, "#"); // 공백문자 전까지 tokenize하여 저장
if (strcmp(title, " ") == 0) // 이름이 존재하지 않는다면
title = NULL;
else
title = strdup(title); // 이름을 복제하여 저장
path = strtok(NULL, "#"); // 공백문자 전까지 tokenize하여 저장
if (strcmp(path, " ") == 0) // 이름이 존재하지 않는다면
path = NULL;
else
path = strdup(path); // 이름을 복제하여 저장
printf("%s %s %s\n", name, title, path);
}
}
'Information Technology > C' 카테고리의 다른 글
[C언어] MP3 관리프로그램(5) (0) | 2020.02.20 |
---|---|
[C언어] MP3 관리 프로그램(3) (0) | 2020.01.29 |
[C언어] MP3 관리 프로그램(2) (0) | 2020.01.29 |
[C언어] MP3 관리 프로그램(1) (0) | 2020.01.28 |
[C언어] 이중 연결 리스트 (0) | 2020.01.20 |