• 구조체 선언 (이름, 나이, 소속)
  • 선언한 구조체 타입대로 정보 입력, 입력하고싶은 개수만큼 
  • 입력 된 정보는 바이너리파일 형태로 저장 (누적되어 쌓임)
  • 이렇게 생성된 바이너리파일에서 정보 파싱해서 출력하기 (이름 순 정렬해서)
  • 사용자가 입력한 문자열이 포함된 이름 검색, 그 직원의 이름/나이/소속 뿌리기
  • 위 기능을 메뉴로 짜서 왔다갔다 가능하게

알게된 것 중 제일 재밌고 중요한건 feof가 0이아닌 값을 뱉어내는 시점. 
(인간입장에서) 파일이 끝났어도, fread를 한번 더 해야 시그널값이 바뀌면서 안다.
위 로직을 잘 고려해서 코드짜야됨.
 
$ cat bfile.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct _employee
{
    char name[10];
    int  age;
    char company[20];
}employee;

employee employee1;

int input(void);
int read_all(void);
int search();

int main (void)
{
    int func_num;

    printf("1) 새로운 직원 정보 입력\n");
    printf("2) 이름으로 직원 검색\n");
    printf("3) 전체 직원목록 확인( 이름 순 정렬) \n");
    printf("4) 종료\n");
    printf("=> 뭘할건지숫자를선택하시오: ");
    scanf("%d", &func_num);

    switch (func_num)
    {
        case 1 :
            input();
            break;

        case 2 :
            search();
            break;

        case 3 :
            read_all();
            break;

        case 4 :
            return 0;
            break;

        default :
            printf("\nERR! 1~4 중 숫자  입력하세요!!!!\n");
            break;
    }

    return 0;
}

/* 직원정보입력*/
int input (void)
{
    FILE *fp;

    fp = fopen("a.bin", "a+b");

    if (fp == NULL)
    {
        printf("실패-종료\n");
        return 1;
    }

    printf("직원 정보 입력\n");
    printf("이름:");
    scanf("%s", employee1.name);
    printf("나이:");
    scanf("%d", &(employee1.age));
    printf("소속:");
    scanf("%s", employee1.company);

    fwrite(&employee1, sizeof(employee1), 1, fp);

    //printf("sizeof(employee1) : %ld\n", sizeof(employee1));

    fclose(fp);
    printf("=> 파일에입력완료\n\n");

    int func_num;

    printf("1) 다른 정보 계속입력하기\n");
    printf("2) 종료\n");
    printf("3) 처음으로\n");
    printf("=> 뭘할건지숫자를선택하시오: ");
    scanf("%d", &func_num);

    switch (func_num)
    {
        case 1 :
            input();
            break;

        case 2 :
            return 0;
            break;

        case 3 :
            main();
            break;

        default :
            printf("\nERR! 1~4 중 숫자  입력하세요!!!!\n");
            break;
    }

    return 0;
}

/* 모든 정보 직원이름순으로 정렬하여 뿌리기*/
int read_all (void)
{
    FILE *fp;
    fp = fopen("a.bin", "rb");

    if (fp == NULL)
    {
        printf("실패-종료\n");
        return 1;
    }

    /* 이렇게하니까 맨 처음만 읽음*/
    //fread((void*)&employee1, sizeof(employee1), 100, fp);

    /* 이름순 정렬을.... 따로 선언해서 담고 소팅해야하나 */
    int CNT = 0;

    while ( feof(fp) == 0 )
    {
        fseek(fp, CNT*sizeof(employee1), SEEK_SET);
        //memset ( &employee1 , 0x00 , sizeof(employee1) );

        fread(&employee1, sizeof(employee1), 1, fp);

        if ( feof(fp) == 0 )
        {
            CNT++;
        }
    }
    //printf(" CNT ( out of while) : %d\n", CNT);
    /* 아니왜 마지막에 입력한게  한번더 읽히냐고.. 매우알게됨 : feof가 시그널바뀌는 시점. fread 함더*/

    fclose(fp);

    //while문 아예 돌지도않아. 파일 닫고 다시 해보자.
    employee employee2[CNT];

    FILE *fp2;
    fp2 = fopen("a.bin", "rb");

    if (fp2 == NULL)
    {
        printf("실패-종료\n");
        return 1;
    }

    int CNT_ARR = 0;

    while (feof(fp2) == 0)
    {

        fseek(fp2, CNT_ARR*sizeof(employee1), SEEK_SET);
        fread(&employee1, sizeof(employee1), 1, fp2);

        strcpy(employee2[CNT_ARR].name, employee1.name);
        employee2[CNT_ARR].age  = employee1.age;
        strcpy(employee2[CNT_ARR].company, employee1.company);

        if ( feof(fp2) == 0 )
        {
            CNT_ARR++;
        }
    }

    int i, j;
    char temp_name[10];
    int  temp_age;
    char temp_company[20];

    for ( i=0; i<CNT_ARR; i++)
    {   
        for ( j=0; j<CNT_ARR-(i+1); j++)
        {   
            if (strcmp(employee2[j].name, employee2[j+1].name) > 0 )
            {   
                strcpy (temp_name, employee2[j].name);
                temp_age =  employee2[j].age;
                strcpy (temp_company, employee2[j].company);

                strcpy (employee2[j].name, employee2[j+1].name);
                employee2[j].age = employee2[j+1].age;
                strcpy (employee2[j].company, employee2[j+1].company);

                strcpy (employee2[j+1].name, temp_name);
                employee2[j+1].age = temp_age;
                strcpy (employee2[j+1].company, temp_company);
            }   
        }   
    }  

    for (i=0; i<CNT_ARR; i++)
    {   
        printf("\n====%dst employee's information ====\n", i+1);
        printf("name:%s\n", employee2[i].name);
        printf("age:%d\n", employee2[i].age);
        printf("company:%s\n", employee2[i].company);
    }

    fclose(fp2);

    return 0;
}


/* 이름으로 검색해서 정보 뿌리기 */
int search (void)
{

    char search[10];
    //char *search_ptr;
    char *ptr;
    //search_ptr = &search;

    FILE *fp;
    fp = fopen("a.bin", "rb");

    if (fp == NULL)
    {
        printf("실패-종료\n");
        return 1;
    }


    printf("검색할 문자열 입력 :");
    scanf("%s", search);

    int CNT = 0;

    while (feof(fp)  == 0)
    {
        //printf("whlie start feof(fp) %d\n", feof(fp));
        //printf("whlie start CNT %d\n", CNT);
        fseek(fp, CNT*sizeof(employee1), SEEK_SET);
        fread(&employee1, sizeof(employee1), 1, fp);

        //ptr = strstr( employee1.name, search_ptr );
        ptr = strstr( employee1.name, search );

        if (feof(fp) == 0 )
        {
            CNT++;
        }
        else if (feof(fp) != 0)
        {
            printf("...............file end : NO MORE RESULT\n");
            exit(0);
        }

        if ( ptr != NULL )
        {
            printf (" === result ( name like < %s > ) === \n", search);
            printf (" name : %s\n", employee1.name);
            printf (" age : %d\n", employee1.age);
            printf (" company : %s\n\n", employee1.company);
        }

        //printf("whlie end feof(fp) %d\n", feof(fp));
        //printf("whlie end CNT %d\n", CNT);
    }

    fclose(fp);

    return 0;
}



+ Recent posts