2005. 3. 17. 15:48

gil

OldPapers/linux 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;
                }
        }
}