2016年7月8日金曜日

C言語:簡易住所録(簡単なインメモリーDB)

問題1
下記の条件で構造体を用いた簡易住所録を作成。
・レコード内容:ID(2ケタ)、氏名、住所(簡単なもの)
・参照・追加・更新・削除が可能
・最初から5件分のメモリ領域を確保しておき、
6件以上登録する場合は随時動的にメモリを確保する(制限無し)
・[Ctrl+c]を押すことで現在の情報をディスク上へファイルとして生成

問題1のプログラム
#define DEFALUT_NUM 5

/* Global Variable*/
typedef struct {
    int id;
    char name[15];
    char address[200];
    int delflag;
} card_t;

card_t *info,*tmp_info;
int current_id=1;

/*Function*/

void genCSV() {
    int i=1;
    FILE *fp;
    fp = fopen("test.dat","w");
    if( fp==NULL ){
        fprintf(stderr,"test.dat can not be opened!\n");
    }
    while ( i < current_id ) {
        if ( info[i].delflag == 0 ) {
            fprintf(fp,"%d,%s,%s\n",info[i].id,info[i].name,info[i].address);
        }
        i++;
    }
    fclose(fp);
}


/* FLG */

/*Signal Handle*/
void endfunc()
{
    genCSV();
    free(info);
    exit(0);
}

typedef void (*handler_t) (int);
static int sigHandlerSet(int sig, handler_t handler)
{

    struct sigaction new_action;
    struct sigaction old_action;
    memset( &new_action, 0, sizeof( struct sigaction ) );
    new_action.sa_handler = handler;
    /* Temporarily block all other signals during handler execution */
    sigfillset ( &new_action.sa_mask );
    /* Auto restart syscalls after handler return */
    new_action.sa_flags = SA_RESTART;

    if ( sigaction( sig, NULL, &old_action ) != 0 )
    {
        return -1;
    }

    /* Honor inherited SIG_IGN that's set by some shell's */
    if ( old_action.sa_handler != SIG_IGN )
    {
        if ( sigaction( sig, &new_action, NULL ) != 0 )
        {
            return -1;
        }
    }
    return 0;
}

int HandleSignals( void )
{
    if (sigHandlerSet(SIGINT,  endfunc) != 0)
        return -1;
    return 0;
}

void selectAll() {
    int i=1;
    int flag = 0;
    while( i < current_id ) {
        if ( info[i].delflag == 0 ) {
            fprintf(stdout,"id=%d,name=%s,address=%s\n",info[i].id,info[i].name,info[i].address);
            flag = 1;
        }
        i++;
    }
    if ( flag == 0 ) {
        fprintf(stdout,"not found!\n");
    }
}

int selectId(int pid) {
    int i=1;
    int flag=0;
    while( i < current_id ) {
        if ( info[i].id == pid && info[i].delflag == 0 ) {
            fprintf(stdout,"id=%d,name=%s,address=%s\n",info[i].id,info[i].name,info[i].address);
            flag = 1;
            break;
        }
        i++;
    }
    return flag;
}

void insert(char *name,char *address) {
    if ( current_id > DEFALUT_NUM ) {
        tmp_info = (card_t*)realloc(info,(current_id + 1) * sizeof(card_t));
        info = tmp_info;
    }
    info[current_id].delflag = 0;
    info[current_id].id = current_id;
    sprintf(info[current_id].name,"%s",name);
    sprintf(info[current_id].address,"%s",address);
    fprintf(stdout,"stored with id=%d\n",info[current_id].id);
    current_id++;
}

void delete(int pid) {
    info[pid].delflag = 1;
}

void update(int pid,char *name,char *address) {
    sprintf(info[pid].name,"%s",name);
    sprintf(info[pid].address,"%s",address);
}

void printMenu() {
    fprintf(stdout,"Please choose a number from following!\n");
    fprintf(stdout,"1 -> select\n");
    fprintf(stdout,"2 -> insert\n");
    fprintf(stdout,"3 -> update\n");
    fprintf(stdout,"4 -> delete\n\n");
    fprintf(stdout,"menu num[1-4] = ");
}

int main(void) {
    char c[2];
    int i;
    int input=0;
    int id=-1;
    int rc=0;
    char name[15];
    char address[200];

    info = (card_t*) malloc ( sizeof(card_t) * (DEFALUT_NUM + 1) );
    for( i = 0; i < DEFALUT_NUM; i++ ) {
        info[i].id = 0;
        info[i].delflag = 0;
    }

    if ( ( rc = HandleSignals()) != 0 )
        exit(-1);

    while ( 1 ) {
        printMenu();
        scanf("%d",&input);
        switch(input) {
        case 1:
            fprintf(stdout,"id(-1:ALL, or id > 0)-> ");
            scanf("%d",&id);
            if ( id < 0 ) {
                selectAll();
            } else {
                if ( ! selectId(id) ) {
                    fprintf(stdout,"not found!\n");
                };
            }
            break;
        case 2:
            fprintf(stdout,"name-> ");
            scanf("%s",name);
            fprintf(stdout,"address-> ");
            scanf("%s",address);
            insert(name,address);
            break;
        case 3:
            fprintf(stdout,"id-> ");
            scanf("%d",&id);
            if ( id > 0 ) {
                if( selectId(id) ) {
                    fprintf(stdout,"name-> ");
                    scanf("%s",name);
                    fprintf(stdout,"address-> ");
                    scanf("%s",address);
                    update(id,name,address);
                } else {
                    fprintf(stdout,"not found id = %d!\n",id);
                }
            } else {
                fprintf(stderr,"Please set correct id!\n");
            }
            break;
        case 4:
            fprintf(stdout,"id-> ");
            scanf("%d",&id);
            if ( id > 0 ) {
                if( selectId(id) ) {
                    delete(id);
                } else {
                    fprintf(stdout,"not found id = %d!\n",id);
                }
            } else {
                fprintf(stderr,"Please set correct id!\n");
            }
            break;
        default:
            break;
        }

        fprintf(stdout,"do you exit this program?[y|n] ");
        scanf("%s",c);
        if ( c[0] == 'y' ) {
            endfunc();
        }
        fprintf(stdout,"\n\n");


    };

    free(info);

    return 0;
}

忙しさにかまけて、ちゃんと理解できないところがあるので復習しなきゃ。。。
次はpythonへ...