2005. 3. 17. 15:48
#include <stdio.h>
#define MEM_MAX_COUNT 5 // 동적 메모리 할당 시도 횟수
#define NO_SIZE 10
#define NAME_SIZE 20
#define FIND 0
#define NOT_FIND 1
typedef struct single
{
char s_no[NO_SIZE];
char s_name[NAME_SIZE];
struct single *prev;
struct single *next;
}SINGLE;
SINGLE *head, *tail;
void myflush(void)
{
while(getchar()!='\n');
}
// 동적 메모리를 할당해주는 함수
int memory_alloc(SINGLE **ip, int size)
{
register tag ;
tag = 0 ;
// 메모리 동적할당
while( !(*ip = (SINGLE*)malloc(sizeof(SINGLE)*size)) ) { //free(ip)
//메모리가 부족하다..
puts("메모리 부족하다") ;
if( tag ++ > MEM_MAX_COUNT/*5*/ ) {
return -1 ;
// exit(-1) ;
}
sleep(1) ;
}
return 0;
}
// 숫자를 입력 받는 함수
int get_decimal(void)
{
int id;
char *str;
int i;
id=1;
do
{
gets(str);
for(i=0; i<strlen(str); i++)
{
if( !(isdigit(str[i])) && str[i]!='-' )
{
printf("정수가 아니니 다시 입력하세요.\n");
id = 1;
break;
}
else id=0;
}
// 만약에 입력 스트링이 정수라면 int형으로 변환
if(id==0)
{
return atoi(str);
}
}
while(id);
}
// 초기화 하는 함수
int init(void)
{
head = (SINGLE *) malloc(sizeof(SINGLE));
if (head == NULL) return -1;
tail = (SINGLE *) malloc(sizeof(SINGLE));
if( tail == NULL)
{
free(head);
return -1;
}
// if ( memory_alloc( (SINGLE **)&head, 1 ) == -1 ) return -1;
// if ( memory_alloc( (SINGLE **)&tail, 1 ) == -1 )
// {
// free(head);
// return -1;
// }
// head, tail 링크연결
head->prev = head;
head->next = tail;
tail->prev = head;
tail->next = tail;
return 0;
}
int menu(void)
{
int i;
printf("\n\n");
printf("=======이중 링크드 리스트=======\n");
printf("1. Insert [ i)head ii)tail ] \n");
printf("2. Display [ i)head ii)tail ] \n");
printf("3. Save \n");
printf("4. Open \n");
printf("5. Sort [ i)no ii)name ] \n");
printf("6. Search [ i)no ii)name ] \n");
printf("7. Exit \n");
printf("select ?");
scanf("%i", &i);
myflush();
return i;
}
int insert_menu(void)
{
int i;
printf("\n\n");
printf("===============Insert=============\n");
printf("1. head\n");
printf("2. tail\n");
printf("3. 중지\n");
printf("select ?");
scanf("%i", &i);
myflush();
return i;
}
int display_menu(void)
{
int i;
printf("\n\n");
printf("===============Display=============\n");
printf("1. head\n");
printf("2. tail\n");
printf("3. 중지\n");
printf("select ?");
scanf("%i", &i);
myflush();
return i;
}
int sort_menu(void)
{
int i;
printf("\n\n");
printf("===============Sort=============\n");
printf("1. no\n");
printf("2. name\n");
printf("3. 중지\n");
printf("select ?");
scanf("%i", &i);
myflush();
return i;
}
int search_menu(void)
{
int i;
printf("\n\n");
printf("===============Search=============\n");
printf("1. no\n");
printf("2. name\n");
printf("3. 중지\n");
printf("select ?");
scanf("%i", &i);
myflush();
return i;
}
// 헤드 삽입하는 함수
int head_insert(void)
{
SINGLE *temp;
temp = (SINGLE *) malloc(sizeof(SINGLE));
if(temp==NULL) return -1;
// if ( memory_alloc( (SINGLE **)&temp, 1 ) == -1 ) return -1;
// 데이타 입력
printf("s_no :");
gets(temp->s_no);
printf("s_name :");
gets(temp->s_name);
// 링크 연결
temp->prev = head->next->prev;
temp->next = head->next;
head->next->prev = temp;
head->next = temp;
return 0;
}
// 테일 삽입하는 함수
int tail_insert(void)
{
SINGLE *temp;
temp = (SINGLE *) malloc(sizeof(SINGLE));
if(temp==NULL) return -1;
// if ( memory_alloc( (SINGLE **)&temp, 1 ) == -1 ) return -1;
// 데이타 입력
printf("s_no :");
gets(temp->s_no);
printf("s_name :");
gets(temp->s_name);
// 링크 연결
temp->prev = tail->prev;
temp->next = tail->prev->next;
tail->prev->next = temp;
tail->prev = temp;
return 0;
}
// 헤드 출력하는 함수
void head_display(void)
{
SINGLE *temp;
printf("===================================\n");
printf("= s-no s-name =\n");
printf("===================================\n");
temp = head->next;
while(temp!=tail)
{
printf(" %10s %20s \n", temp->s_no, temp->s_name);
temp=temp->next;
}
}
// 테일 출력하는 함수
void tail_display(void)
{
SINGLE *temp;
printf("===================================\n");
printf("= s-no s-name =\n");
printf("===================================\n");
temp = tail->prev;
while(temp!=head)
{
printf(" %10s %20s \n", temp->s_no, temp->s_name);
temp=temp->prev;
}
}
void no_sort(void)
{
SINGLE *temp;
SINGLE *sort_ind;
SINGLE *i1;
SINGLE *i2;
temp=head->next;
sort_ind=tail;
while(sort_ind!=head->next)
{
temp=head->next;
while(temp->sort_ind->prev)
{
if(atoi(temp->s_no) > atoi(temp->next->s_no) )
{
i1=temp; i2=temp->next;
i1->prev->next=i2;
i2->next->prev=i1;
i2->prev=i1->prev;
i1->prev=i2
}
else temp=temp->next;
}
sort_ind=sort_ind->prev;
}
printf("no sort\n");
}
void name_sort(void)
{
printf("name sort\n");
}
int find_no_element(char ch)
{
SINGLE *temp;
int i;
int find;
char no[NO_SIZE];
temp = head->next;
printf("===================================\n");
printf("= s-no s-name =\n");
printf("===================================\n");
find = NOT_FIND;
while(temp!=tail)
{
for(i=0; i<strlen(temp->s_no); i++)
{
strcpy( no, temp->s_no);
if( no[i] == ch)
{
printf(" %10s %20s \n", temp->s_no, temp->s_name);
find = FIND;
break;
}
}
temp=temp->next;
}
if( find == NOT_FIND ) printf("못찾았습니다.\n");
}
void no_search(void)
{
int i;
char ch;
printf("no search\n");
printf("번호를 입력하세요:");
scanf("%c", &ch);
myflush();
/*
printf("번호를 입력하세요:");
i = get_decimal();
*/
find_no_element(ch);
}
int find_name_element(char ch)
{
SINGLE *temp;
int i;
int find;
char name[NAME_SIZE];
temp = head->next;
printf("===================================\n");
printf("= s-no s-name =\n");
printf("===================================\n");
find = NOT_FIND;
while(temp!=tail)
{
for(i=0; i<strlen(temp->s_name); i++)
{
strcpy( name, temp->s_name);
if( name[i] == ch)
{
printf(" %10s %20s \n", temp->s_no, temp->s_name);
find = FIND;
break;
}
}
temp=temp->next;
}
if( find == NOT_FIND ) printf("못찾았습니다.\n");
}
void name_search(void)
{
// 단어 입력 받는 버퍼
char ch;
printf("name search\n");
printf("문자를 입력하세요:");
scanf("%c", &ch);
myflush();
find_name_element(ch);
}
void insert(void)
{
int i;
while(1) // 무한 루프
{
switch( i = insert_menu() )
{
case 1: head_insert(); break;
case 2: tail_insert(); break;
case 3: return;
default : break;
}
}
}
void display(void)
{
int i;
while(1) // 무한 루프
{
switch( i = display_menu() )
{
case 1: head_display();
printf("===========end of display==========\n");
break;
case 2: tail_display();
printf("===========end of display==========\n");
break;
case 3: return;
default : break;
}
}
}
int save(void)
{
FILE *fp;
SINGLE *temp;
char a,*file_name;
printf("\n\n");
printf("=============파일저장===========\n");
printf("default[SINGLE.DAT] 다른 파일명을 원하십니까?(y/n)");
scanf("%c",&a);
myflush();
if( a== 'y')
{
printf("파일명을 입력해주십시오.");
scanf("%s",file_name);
fp = fopen(file_name,"w+t");
}
else
{
fp = fopen("SINGLE.DAT","w+t");
}
if(fp == NULL) exit(-1);
if(feof(fp)!=0) printf("쓰기전 파일이 비어있습니다.\n");
if(feof(fp)==0) printf("쓰기전 파일이 비어있지 않습니다.\n");
//헤드에는 데이타가 없다.
temp = head->next;
if(temp == tail) printf("링크가 비어있습니다.\n");
while(temp != tail)
{
// 링크 사이즈는 빼준다. 이중링크이므로 2번 빼준다.
fwrite(temp, sizeof(SINGLE)-sizeof(SINGLE*)-sizeof(SINGLE*), 1, fp);
printf("파일에 링크를 삽입했습니다.\n");
// 다음 데이타가 있는 곳
temp= temp->next;
}
if(feof(fp)!=0) printf("쓰기후 파일이 비어있습니다.\n");
if(feof(fp)==0) printf("쓰기후 파일이 비어있지 않습니다.\n");
// 파일 저장과 닫기
fclose(fp);
return 0;
}
int open(void)
{
FILE *fp;
SINGLE *temp;
SINGLE *buf;
char *file_name;
printf("\n\n");
printf("=============파일입력===========\n");
// 이중링크가 비어있는지 검사
if( head->next != tail )
{
printf("입력 전 링크가 비어있지 않습니다.\n");
// 이중링크가 비어있지 않다면 기존에 있는 링크 모두 삭제
while(head->next != tail)
{
// 다음 데이타가 있는 곳
temp = head->next; // 잊지말것 temp는 4byte pointer!!!
head->next = temp->next;
temp->next->prev = head;
free(temp);
}
printf("기존의 링크를 모두 지웠습니다.\n");
head_display();
printf("===========end of display==========\n");
}
if( head->next == tail )
{
printf("입력 전 링크가 비어있습니다.\n");
printf("open할 파일이름을 입력해 주세요:");
scanf("%s",file_name);
fp = fopen(file_name,"rt");
if(fp == NULL) exit(-1);
else printf("파일 읽기 성공\n");
while(1)
{
buf = (SINGLE *) malloc(sizeof(SINGLE));
if (buf == NULL)
{
printf("메모리할당실패");
// 파일 저장과 닫기
fclose(fp);
return -1;
}
// if ( memory_alloc( (SINGLE **)&buf, 1 ) == -1 )
// {
// printf("메모리할당실패");
// return -1;
// }
// 파일에서 데이터를 읽어 온다.
fread(buf,sizeof(SINGLE)-sizeof(SINGLE*)-sizeof(SINGLE*), 1, fp); // 1개
// 파일의 끝이면 종료
if(feof(fp)!=0) break;
// 링크 연결 tail에 삽입하는 방법!!!
buf->prev = tail->prev;
buf->next = tail->prev->next;
tail->prev->next = buf;
tail->prev = buf;
printf("링크 삽입\n");
}
// // buf가 함수의 리턴과 함께 더이상 쓰이지 않으므로
// free(buf);
// 파일 저장과 닫기
fclose(fp);
}
if( head->next == tail ) printf("입력 후 링크가 비어있습니다.\n");
if( head->next != tail ) printf("입력 후 링크가 비어있지 않습니다.\n");
}
void sort(void)
{
int i;
while(1) // 무한 루프
{
switch( i = sort_menu() )
{
case 1: no_sort(); break;
case 2: name_sort(); break;
case 3: return;
default : break;
}
}
}
void search(void)
{
int i;
while(1) // 무한 루프
{
switch( i = search_menu() )
{
case 1: no_search(); break;
case 2: name_search(); break;
case 3: return;
default : break;
}
}
}
main()
{
int i;
if( init() != 0 )
{
printf("초기화 실패\n");
exit(-1);
}
while(1) // 무한 루프
{
switch( i = menu() )
{
case 1: insert(); break;
case 2: display(); break;
case 3: save(); break;
case 4: open(); break;
case 5: sort(); break;
case 6: search(); break;
case 7: exit(0); break;
default : break;
}
}
}
#define MEM_MAX_COUNT 5 // 동적 메모리 할당 시도 횟수
#define NO_SIZE 10
#define NAME_SIZE 20
#define FIND 0
#define NOT_FIND 1
typedef struct single
{
char s_no[NO_SIZE];
char s_name[NAME_SIZE];
struct single *prev;
struct single *next;
}SINGLE;
SINGLE *head, *tail;
void myflush(void)
{
while(getchar()!='\n');
}
// 동적 메모리를 할당해주는 함수
int memory_alloc(SINGLE **ip, int size)
{
register tag ;
tag = 0 ;
// 메모리 동적할당
while( !(*ip = (SINGLE*)malloc(sizeof(SINGLE)*size)) ) { //free(ip)
//메모리가 부족하다..
puts("메모리 부족하다") ;
if( tag ++ > MEM_MAX_COUNT/*5*/ ) {
return -1 ;
// exit(-1) ;
}
sleep(1) ;
}
return 0;
}
// 숫자를 입력 받는 함수
int get_decimal(void)
{
int id;
char *str;
int i;
id=1;
do
{
gets(str);
for(i=0; i<strlen(str); i++)
{
if( !(isdigit(str[i])) && str[i]!='-' )
{
printf("정수가 아니니 다시 입력하세요.\n");
id = 1;
break;
}
else id=0;
}
// 만약에 입력 스트링이 정수라면 int형으로 변환
if(id==0)
{
return atoi(str);
}
}
while(id);
}
// 초기화 하는 함수
int init(void)
{
head = (SINGLE *) malloc(sizeof(SINGLE));
if (head == NULL) return -1;
tail = (SINGLE *) malloc(sizeof(SINGLE));
if( tail == NULL)
{
free(head);
return -1;
}
// if ( memory_alloc( (SINGLE **)&head, 1 ) == -1 ) return -1;
// if ( memory_alloc( (SINGLE **)&tail, 1 ) == -1 )
// {
// free(head);
// return -1;
// }
// head, tail 링크연결
head->prev = head;
head->next = tail;
tail->prev = head;
tail->next = tail;
return 0;
}
int menu(void)
{
int i;
printf("\n\n");
printf("=======이중 링크드 리스트=======\n");
printf("1. Insert [ i)head ii)tail ] \n");
printf("2. Display [ i)head ii)tail ] \n");
printf("3. Save \n");
printf("4. Open \n");
printf("5. Sort [ i)no ii)name ] \n");
printf("6. Search [ i)no ii)name ] \n");
printf("7. Exit \n");
printf("select ?");
scanf("%i", &i);
myflush();
return i;
}
int insert_menu(void)
{
int i;
printf("\n\n");
printf("===============Insert=============\n");
printf("1. head\n");
printf("2. tail\n");
printf("3. 중지\n");
printf("select ?");
scanf("%i", &i);
myflush();
return i;
}
int display_menu(void)
{
int i;
printf("\n\n");
printf("===============Display=============\n");
printf("1. head\n");
printf("2. tail\n");
printf("3. 중지\n");
printf("select ?");
scanf("%i", &i);
myflush();
return i;
}
int sort_menu(void)
{
int i;
printf("\n\n");
printf("===============Sort=============\n");
printf("1. no\n");
printf("2. name\n");
printf("3. 중지\n");
printf("select ?");
scanf("%i", &i);
myflush();
return i;
}
int search_menu(void)
{
int i;
printf("\n\n");
printf("===============Search=============\n");
printf("1. no\n");
printf("2. name\n");
printf("3. 중지\n");
printf("select ?");
scanf("%i", &i);
myflush();
return i;
}
// 헤드 삽입하는 함수
int head_insert(void)
{
SINGLE *temp;
temp = (SINGLE *) malloc(sizeof(SINGLE));
if(temp==NULL) return -1;
// if ( memory_alloc( (SINGLE **)&temp, 1 ) == -1 ) return -1;
// 데이타 입력
printf("s_no :");
gets(temp->s_no);
printf("s_name :");
gets(temp->s_name);
// 링크 연결
temp->prev = head->next->prev;
temp->next = head->next;
head->next->prev = temp;
head->next = temp;
return 0;
}
// 테일 삽입하는 함수
int tail_insert(void)
{
SINGLE *temp;
temp = (SINGLE *) malloc(sizeof(SINGLE));
if(temp==NULL) return -1;
// if ( memory_alloc( (SINGLE **)&temp, 1 ) == -1 ) return -1;
// 데이타 입력
printf("s_no :");
gets(temp->s_no);
printf("s_name :");
gets(temp->s_name);
// 링크 연결
temp->prev = tail->prev;
temp->next = tail->prev->next;
tail->prev->next = temp;
tail->prev = temp;
return 0;
}
// 헤드 출력하는 함수
void head_display(void)
{
SINGLE *temp;
printf("===================================\n");
printf("= s-no s-name =\n");
printf("===================================\n");
temp = head->next;
while(temp!=tail)
{
printf(" %10s %20s \n", temp->s_no, temp->s_name);
temp=temp->next;
}
}
// 테일 출력하는 함수
void tail_display(void)
{
SINGLE *temp;
printf("===================================\n");
printf("= s-no s-name =\n");
printf("===================================\n");
temp = tail->prev;
while(temp!=head)
{
printf(" %10s %20s \n", temp->s_no, temp->s_name);
temp=temp->prev;
}
}
void no_sort(void)
{
SINGLE *temp;
SINGLE *sort_ind;
SINGLE *i1;
SINGLE *i2;
temp=head->next;
sort_ind=tail;
while(sort_ind!=head->next)
{
temp=head->next;
while(temp->sort_ind->prev)
{
if(atoi(temp->s_no) > atoi(temp->next->s_no) )
{
i1=temp; i2=temp->next;
i1->prev->next=i2;
i2->next->prev=i1;
i2->prev=i1->prev;
i1->prev=i2
}
else temp=temp->next;
}
sort_ind=sort_ind->prev;
}
printf("no sort\n");
}
void name_sort(void)
{
printf("name sort\n");
}
int find_no_element(char ch)
{
SINGLE *temp;
int i;
int find;
char no[NO_SIZE];
temp = head->next;
printf("===================================\n");
printf("= s-no s-name =\n");
printf("===================================\n");
find = NOT_FIND;
while(temp!=tail)
{
for(i=0; i<strlen(temp->s_no); i++)
{
strcpy( no, temp->s_no);
if( no[i] == ch)
{
printf(" %10s %20s \n", temp->s_no, temp->s_name);
find = FIND;
break;
}
}
temp=temp->next;
}
if( find == NOT_FIND ) printf("못찾았습니다.\n");
}
void no_search(void)
{
int i;
char ch;
printf("no search\n");
printf("번호를 입력하세요:");
scanf("%c", &ch);
myflush();
/*
printf("번호를 입력하세요:");
i = get_decimal();
*/
find_no_element(ch);
}
int find_name_element(char ch)
{
SINGLE *temp;
int i;
int find;
char name[NAME_SIZE];
temp = head->next;
printf("===================================\n");
printf("= s-no s-name =\n");
printf("===================================\n");
find = NOT_FIND;
while(temp!=tail)
{
for(i=0; i<strlen(temp->s_name); i++)
{
strcpy( name, temp->s_name);
if( name[i] == ch)
{
printf(" %10s %20s \n", temp->s_no, temp->s_name);
find = FIND;
break;
}
}
temp=temp->next;
}
if( find == NOT_FIND ) printf("못찾았습니다.\n");
}
void name_search(void)
{
// 단어 입력 받는 버퍼
char ch;
printf("name search\n");
printf("문자를 입력하세요:");
scanf("%c", &ch);
myflush();
find_name_element(ch);
}
void insert(void)
{
int i;
while(1) // 무한 루프
{
switch( i = insert_menu() )
{
case 1: head_insert(); break;
case 2: tail_insert(); break;
case 3: return;
default : break;
}
}
}
void display(void)
{
int i;
while(1) // 무한 루프
{
switch( i = display_menu() )
{
case 1: head_display();
printf("===========end of display==========\n");
break;
case 2: tail_display();
printf("===========end of display==========\n");
break;
case 3: return;
default : break;
}
}
}
int save(void)
{
FILE *fp;
SINGLE *temp;
char a,*file_name;
printf("\n\n");
printf("=============파일저장===========\n");
printf("default[SINGLE.DAT] 다른 파일명을 원하십니까?(y/n)");
scanf("%c",&a);
myflush();
if( a== 'y')
{
printf("파일명을 입력해주십시오.");
scanf("%s",file_name);
fp = fopen(file_name,"w+t");
}
else
{
fp = fopen("SINGLE.DAT","w+t");
}
if(fp == NULL) exit(-1);
if(feof(fp)!=0) printf("쓰기전 파일이 비어있습니다.\n");
if(feof(fp)==0) printf("쓰기전 파일이 비어있지 않습니다.\n");
//헤드에는 데이타가 없다.
temp = head->next;
if(temp == tail) printf("링크가 비어있습니다.\n");
while(temp != tail)
{
// 링크 사이즈는 빼준다. 이중링크이므로 2번 빼준다.
fwrite(temp, sizeof(SINGLE)-sizeof(SINGLE*)-sizeof(SINGLE*), 1, fp);
printf("파일에 링크를 삽입했습니다.\n");
// 다음 데이타가 있는 곳
temp= temp->next;
}
if(feof(fp)!=0) printf("쓰기후 파일이 비어있습니다.\n");
if(feof(fp)==0) printf("쓰기후 파일이 비어있지 않습니다.\n");
// 파일 저장과 닫기
fclose(fp);
return 0;
}
int open(void)
{
FILE *fp;
SINGLE *temp;
SINGLE *buf;
char *file_name;
printf("\n\n");
printf("=============파일입력===========\n");
// 이중링크가 비어있는지 검사
if( head->next != tail )
{
printf("입력 전 링크가 비어있지 않습니다.\n");
// 이중링크가 비어있지 않다면 기존에 있는 링크 모두 삭제
while(head->next != tail)
{
// 다음 데이타가 있는 곳
temp = head->next; // 잊지말것 temp는 4byte pointer!!!
head->next = temp->next;
temp->next->prev = head;
free(temp);
}
printf("기존의 링크를 모두 지웠습니다.\n");
head_display();
printf("===========end of display==========\n");
}
if( head->next == tail )
{
printf("입력 전 링크가 비어있습니다.\n");
printf("open할 파일이름을 입력해 주세요:");
scanf("%s",file_name);
fp = fopen(file_name,"rt");
if(fp == NULL) exit(-1);
else printf("파일 읽기 성공\n");
while(1)
{
buf = (SINGLE *) malloc(sizeof(SINGLE));
if (buf == NULL)
{
printf("메모리할당실패");
// 파일 저장과 닫기
fclose(fp);
return -1;
}
// if ( memory_alloc( (SINGLE **)&buf, 1 ) == -1 )
// {
// printf("메모리할당실패");
// return -1;
// }
// 파일에서 데이터를 읽어 온다.
fread(buf,sizeof(SINGLE)-sizeof(SINGLE*)-sizeof(SINGLE*), 1, fp); // 1개
// 파일의 끝이면 종료
if(feof(fp)!=0) break;
// 링크 연결 tail에 삽입하는 방법!!!
buf->prev = tail->prev;
buf->next = tail->prev->next;
tail->prev->next = buf;
tail->prev = buf;
printf("링크 삽입\n");
}
// // buf가 함수의 리턴과 함께 더이상 쓰이지 않으므로
// free(buf);
// 파일 저장과 닫기
fclose(fp);
}
if( head->next == tail ) printf("입력 후 링크가 비어있습니다.\n");
if( head->next != tail ) printf("입력 후 링크가 비어있지 않습니다.\n");
}
void sort(void)
{
int i;
while(1) // 무한 루프
{
switch( i = sort_menu() )
{
case 1: no_sort(); break;
case 2: name_sort(); break;
case 3: return;
default : break;
}
}
}
void search(void)
{
int i;
while(1) // 무한 루프
{
switch( i = search_menu() )
{
case 1: no_search(); break;
case 2: name_search(); break;
case 3: return;
default : break;
}
}
}
main()
{
int i;
if( init() != 0 )
{
printf("초기화 실패\n");
exit(-1);
}
while(1) // 무한 루프
{
switch( i = menu() )
{
case 1: insert(); break;
case 2: display(); break;
case 3: save(); break;
case 4: open(); break;
case 5: sort(); break;
case 6: search(); break;
case 7: exit(0); break;
default : break;
}
}
}