단순 연결리스트에 파일 입출력을 응용
구조체 정의
1 2 3 4 5 6 7 8 | #define LEN 20 typedef char LData[LEN]; typedef struct _node { LData data; struct _node * next; } Node | cs |
연결 리스트의 초기화
1 2 3 4 5 6 7 8 9 10 | Node * head, * tail; // 전역 변수 void list_init(void) { head = (Node*)calloc(1, sizeof(Node)); tail = (Node*)calloc(1, sizeof(Node)); head->next = tail; tail->next = tail; } | cs |
데이터 입력받음
1 2 3 4 5 6 7 8 9 10 | static char data[LEN]; void Data_insert() { printf("이름 입력:"); fgets(data, sizeof(data), stdin); while (getchar() != '\n'); Node_insert(data); } | cs |
노드의 삽입
1 2 3 4 5 6 7 8 | void Node_insert(char *data) { Node *t; t = (Node * )calloc(1, sizeof(Node)); strcpy(t->data, data); t->next = head->next; head->next = t; } | cs |
node L을 추가한 다음 node I를 추가하면 head - I - L - tail 순으로 연결이 된다. tail->next는 NULL로 초기화하지 않고 tail 자신을 가리키도록 했다.
조회하고 출력할 때, 마지막에 들어간 데이터가 가장 먼저 출력된다.
연결리스트를 파일로 저장
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | void save_File() { FILE *fp; fp = fopen("DATA.DBF", "wb"); Book *t; if (fp == NULL) { printf(" 오류 \n"); return; } t = head->next; while (t != tail) { fwrite(t, sizeof(LEN), 1, fp); t = t->next; } fclose(fp); } | cs |
*t가 tail을 가리킬 때까지 (추가할 필요가 노드가 없게 될때까지) 각 노드를 추가한다.
파일을 읽어들여 연결리스트로 구성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | void load_File() { FILE *fp; fp = fopen("BOOK.DBF", "rb"); Book *p; Book *s; if (fp == NULL) { printf(" 오류 \n"); return; } p = head->next; /* 파일을 읽기 전 모든 노드 삭제하는 과정 시작 */ while (p != tail) { s = p; p = p->next; free(s); } /* 파일을 읽기 전 모든 노드 삭제하는 과정 끝 */ head->next = tail; // head를 tail과 연결 시켜 준다. while (1) { p = (Book*)calloc(1, sizeof(Book)); if (!fread(p, sizeof(LEN), 1, fp)) // EOF까지 구조체를 읽어들이면서 node를 추가한다. { free(p); break; } p->next = head->next; head->next = p; } fclose(fp); } | cs |
malloc() 함수는 메모리를 할당후 초기화하지 않기 때문에 출력된 파일을 메모장으로 열어보면 데이터를 알아보기 힘들게 된다.
하지만 문자열의 끝은 NULL로 구분하게 되므로 콘솔환경의 파일 입출력시에는 아무 문제없다.
만약 식별하기 쉬운 파일 데이터를 원하면, calloc함수를 통해 동적할당하면 된다. (calloc함수는 모든 비트를 0으로 초기화)
calloc
#include <stdlib.h>
void * calloc(size_t elt_count, size_t elt_size);
malloc 함수와의 차이점은 elt_count x elt_size 크기만큼의 바이트를 동적할당한다는 것이다.
그리고 malloc 함수는 쓰레기값으로 초기화되는것과 달리 calloc는 모든 비트를 0으로 초기화한다.
도서관리 프로그램에 구현된 파일 입출력 기능
종료 메뉴 선택시 save_File() 함수 호출 후, 프로그램을 종료한다.
BOOK.DBF 파일의 내용
프로그램 재실행 후 출력 모습
저장된 파일을 토대로 연결리스트를 구성하면서 처음 입력된 자료가 처음 출력되게 된다.
1 2 3 4 5 6 7 8 9 10 | #include "book.h" int main() { list_init(); // 연결리스트 초기화 load_File(); // 파일을 읽어들임 unsigned int uiMenu; MenuMap stMenu[END] = { ( ...) | cs |
main함수에서는 연결리스트 초기화 후, 파일을 읽어들여 연결리스트로 재구성한다.
'Data Structure' 카테고리의 다른 글
stack으로 구현하는 계산기 프로그램 (0) | 2016.11.07 |
---|---|
자료 구조 - Stack (0) | 2016.11.05 |
이진 트리의 구현과 순회(Traversal) (0) | 2016.09.12 |
Binary Tree (0) | 2016.09.12 |
Doubly Linked List (0) | 2016.09.09 |