[c言語] さっと復習(16) 簡単なDBを作成する

簡単なDBを作成する。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_MEMBER 10
#define NAME_LENGTH 50
#define MESSAGE_LENGTH 256

enum ERROR {
    MESSAGE_OK,
    MESSAGE_ERROR
};

typedef struct {
    int id;
    char name[NAME_LENGTH];
} member;

// グローバル変数
int num = 0;
member member_databese[MAX_MEMBER];
int Error;

// プロトタイプ宣言
void init_db();
int add(int, char*);
member* get(int);
void show_data(member*);
void show_error();

int main(void) {
    int i;
    char names[][NAME_LENGTH] = {
        "John",
        "Mike",
        "Taro",
        "Hana"
    };
    int ids[] = {1, 2, 3, 4};
    init_db();

    for (i=0; i<4; i++) { 
        add(ids[i], names[i]);
        printf("added id:%d name:%s to db.\n", ids[i], names[i]);
        show_error();
    }

    for (i=0; i<4; i++) {
        show_data(get(i+1));
    }

    return 0;
}

void init_db(void) {
    int i;
    for (i=0; i<MAX_MEMBER; i++) {
        member_databese[i].id = -1;
        strcpy(member_databese[i].name, "");
    }
    Error = MESSAGE_OK;
    num = 0;
}

int add(int id, char* name) {
    if (get(id)==NULL && num < MAX_MEMBER) {
        member_databese[num].id = id;
        strcpy(member_databese[num].name, name);
        num++;
        Error = MESSAGE_OK;
        return 1;
    }
    Error = MESSAGE_ERROR;
    return 0;
}

member* get(int id) {
    int i;
    for (i=0; i<num; i++) {
        if (member_databese[i].id == id) {
            return &member_databese[i];
        }
    }
    return NULL;
}

void show_data(member* data) {
    if (data != NULL) {
        printf("id:%d name:%s \n", data->id, data->name);
    } else {
        printf("No matched data.\n");
    }
}

void show_error() {
    switch (Error) {
        case MESSAGE_OK:
            printf("Finish inserting data.\n");
            break;
        case MESSAGE_ERROR:
            printf("Error occured. Could not insert data.\n");
            break;
    }
}

enum 列挙型

頭から順に0, 1, 2…と整数を割り振る。

ソースの分割

ソースを、ヘッダファイル、メイン関数、その他関数へと分割する。

関数の持つ機能ごとに分割する。

ヘッダファイル

database.h

#ifndef _DATABASE_H_
#define _DATABASE_H_

#define MAX_MEMBER 10
#define NAME_LENGTH 50

enum ERROR {
    MESSAGE_OK,
    MESSAGE_ERROR
};

typedef struct {
    int id;
    char name[NAME_LENGTH];
} member;

void init_db();
int add(int, char*);
member* get(int);

#endif //_DATABASE_H_

output.h

#ifndef _OUTPUT_H_
#define _OUTPUT_H_

#include "database.h"

void show_data(member*);
void show_error();

#endif //_OUTPUT_H_

メイン関数

main.c

#include <stdio.h>
#include "database.h"
#include "output.h"

int main(void) {
    int i;
    char names[][NAME_LENGTH] = {
        "John",
        "Mike",
        "Taro",
        "Hana"
    };
    int ids[] = {1, 2, 3, 4};
    init_db();

    for (i=0; i<4; i++) { 
        add(ids[i], names[i]);
        printf("added id:%d name:%s to db.\n", ids[i], names[i]);
        show_error();
    }

    for (i=0; i<4; i++) {
        show_data(get(i+1));
    }

    return 0;
}

その他関数

database.c

static を関数や変数の前につけると、別のファイルからその変数を参照できなくなる。

C言語のstatic指定子について

#include <string.h>
#include "database.h"

// グローバル変数
static int num = 0;
static member member_databese[MAX_MEMBER];
int Error;

void init_db(void) {
    int i;
    for (i=0; i<MAX_MEMBER; i++) {
        member_databese[i].id = -1;
        strcpy(member_databese[i].name, "");
    }
    Error = MESSAGE_OK;
    num = 0;
}

int add(int id, char* name) {
    if (get(id)==NULL && num < MAX_MEMBER) {
        member_databese[num].id = id;
        strcpy(member_databese[num].name, name);
        num++;
        Error = MESSAGE_OK;
        return 1;
    }
    Error = MESSAGE_ERROR;
    return 0;
}

member* get(int id) {
    int i;
    for (i=0; i<num; i++) {
        if (member_databese[i].id == id) {
            return &member_databese[i];
        }
    }
    return NULL;
}

output.c

#include <stdio.h>
#include "output.h"

extern int Error;


void show_data(member* data) {
    if (data != NULL) {
        printf("id:%d name:%s \n", data->id, data->name);
    } else {
        printf("No matched data.\n");
    }
}

void show_error() {
    switch (Error) {
        case MESSAGE_OK:
            printf("Finish inserting data.\n");
            break;
        case MESSAGE_ERROR:
            printf("Error occured. Could not insert data.\n");
            break;
    }
}