[ create a new paste ] login | about

Link: http://codepad.org/On58lEw2    [ raw code | output | fork ]

C, pasted on Jan 10:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* コマンドの読み込みの最大値 */
#define BUFFER_SIZE 256
/* 患者の最大数 */
#define MAX_NUM_PATIENTS 101
/* 患者の状態の数 */
#define NUM_STATUS_LEVELS 5
/* 名前の長さの最大 */
#define MAX_NAME_LENGTH 51

/* 患者の状態を表す構造体 */
typedef struct patient{
	/* 受付時刻(時) */
	int  hour;
	/* 受付時刻(分) */
	int  minute;
	/* 名前 */
	char name[MAX_NAME_LENGTH];
	/* 状態 */
	int  status;
} patient;

/* 患者のポインタの配列の型 */
typedef patient** patients;
/* 状態別の患者のリスト */
typedef patients* patient_list; 

/********************************/
/* 患者・患者リストの作成・削除 */
/********************************/

/* 患者のエントリを作成する */
void create_patient(patient** ppat){
	(*ppat) = malloc(sizeof(patient));
}
/* 患者のエントリを削除する */
void release_patient(patient* pat){
	free(pat);
}

/* 患者のリストを作成する */
void craete_patient_list(patient_list* plist){
	int i,j;
	(*plist) = malloc(NUM_STATUS_LEVELS * sizeof(patients));
	for(i = 0; i < NUM_STATUS_LEVELS; i++){
		(*plist)[i] = malloc(MAX_NUM_PATIENTS * sizeof(patient*));
		for(j = 0; j < MAX_NUM_PATIENTS; j++){
			(*plist)[i][j] = NULL;
		}
	}
}
/* 患者のリストを削除する */
void release_patient_list(patient_list list){
	int i,j;
	for(i = 0; i < NUM_STATUS_LEVELS; i++){
		for(j = 0; j < MAX_NUM_PATIENTS; j++){
			if(list[i][j] != NULL){
				release_patient(list[i][j]);
			}else{
				break;
			}
		}
		free(list[i]);
	}
	free(list);
}


/**************************/
/* 操作                   */
/**************************/
/* 待ち行列に追加 */
void insert_patient(patient_list list, patient* p){
	patient** it = list[p->status-1];
	while((*it) != NULL){ it++; }
	(*it) = p;
}
/* 待ち行列から削除 */
void remove_patient(patient_list list, patient* p){
	int i,j;
	for(i = 0; i < NUM_STATUS_LEVELS; i++){
		for(j = 0; j < MAX_NUM_PATIENTS; j++){
			if(list[i][j] == NULL) break;
			if(list[i][j] != p) continue;
			for(; j < MAX_NUM_PATIENTS; j++){
				list[i][j] = list[i][j+1];
				if(list[i][j] == NULL) return;
			}
		}
	}
}
/* 次に呼ばれる患者を取得 */
patient* next_pateint(patient_list list){
	int i;
	for(i = NUM_STATUS_LEVELS-1; i >= 0; i--){
		if(list[i][0] != NULL){
			return list[i][0];
		}
	}
	return NULL;
}
/* 名前の一致する患者を探す */
patient* find_patient(patient_list list, char* name){
	int i,j;
	for(i = 0; i < NUM_STATUS_LEVELS; i++){
		for(j = 0; j < MAX_NUM_PATIENTS; j++){
			if(list[i][j] == NULL) break;
			if(strcmp(name, list[i][j]->name) != 0) continue;
			return list[i][j];
		}
	}
	return NULL;
}
/* 待ち行列の内容を全て表示する */
void print_list(patient_list list){
	int i,j;
	printf("Patients:\n");
	for(i = NUM_STATUS_LEVELS-1; i >= 0; i--){
		for(j = 0; j < MAX_NUM_PATIENTS; j++){
			patient* p = list[i][j];
			if(p == NULL) break;
			printf(" %d %02d:%02d %s\n", p->status, p->hour, p->minute, p->name);
		}
	}
}

/**************************/
/* コマンドファイルの実行 */
/**************************/
/* ファイルから1行バッファに読み込む */
int read_line(FILE* fp, char* buff){
	int ret = fscanf(fp, "%[^\n]%*c", buff);
	return ret;
}
/*
 * ファイルに書いてあるコマンドを解釈して実行
 * 実行したコマンドの数を返します。
 * @param fp ファイルポインタ
 * @param list 患者リスト
 */
int interpret_command(FILE* fp, patient_list list){
	char buff[BUFFER_SIZE];
	int command_count = 0;
	patient* pat;
	int hour,minute,status;

	if(fp == NULL) return -1;
	
	while(feof(fp) == 0){
		/* 1行読む */
		read_line(fp, buff);
		if(feof(fp) != 0){
			break;
		}
		else if(buff[0] == 'i'){
			/* 患者の受付 */
			create_patient(&pat);
			read_line(fp, buff);
			sscanf(buff, "%d:%d", &pat->hour, &pat->minute);
			read_line(fp, &pat->name[0]);
			read_line(fp, buff);
			sscanf(buff, "%d", &pat->status);
			insert_patient(list, pat);
		}
		else if(buff[0] == 'r'){
			/* 次の患者の参照 */
			read_line(fp, buff);
			sscanf(buff, "%d:%d", &hour, &minute);
			pat = next_pateint(list);
			if(pat != NULL){
				printf("Next patient:\n");
				printf(" %d %02d:%02d %s\n", pat->status, pat->hour, pat->minute, pat->name);
			}
		}
		else if(buff[0] == 'c'){
			/* 次の患者の呼び出し */
			read_line(fp, buff);
			sscanf(buff, "%d:%d", &hour, &minute);
			pat = next_pateint(list);
			if(pat != NULL){
				remove_patient(list, pat);
				printf("Called patient:\n");
				printf(" %d %02d:%02d %s\n", pat->status, pat->hour, pat->minute, pat->name);
			}
		}
		else if(buff[0] == 'u'){
			/* 指定患者の状態変更 */
			read_line(fp, buff);
			sscanf(buff, "%d:%d", &hour, &minute);
			read_line(fp, buff);
			pat = find_patient(list, buff);
			read_line(fp, buff);
			sscanf(buff, "%d", &status);
			if(pat != NULL && status > pat->status){
				remove_patient(list, pat);
				pat->hour   = hour;
				pat->minute = minute;
				pat->status = status;
				insert_patient(list, pat);
			}
		}
		else if(buff[0] == 'd'){
			/* 患者の削除 */
			read_line(fp, buff);
			sscanf(buff, "%d:%d", &hour, &minute);
			read_line(fp, buff);
			pat = find_patient(list, buff);
			if(pat != NULL){
				/* リストから除外 */
				remove_patient(list, pat);
				/* メモリの解放 */
				release_patient(pat);
			}
		}
		else if(buff[0] == 't'){
			/* 患者の一覧表示 */
			read_line(fp, buff);
			sscanf(buff, "%d:%d", &hour, &minute);
			print_list(list);
		}
		else if(buff[0] == '*'){
			/* 終わり */
			break;
		}
		command_count++;
	}
	return command_count;
}

/*************************/
/* main関数              */
/*************************/
int main(int argc, char* argv[]){
	/* コマンドファイルのファイルポインタ */
	FILE* fp;
	/* 患者リスト */
	patient_list list;

	/* 引数が渡されていなければ異常終了する */
	if(argc != 2) return 1;

	/* コマンドファイルを開く */
	fp = fopen(argv[1], "r");
	if(fp == NULL) return 2;
	/* 患者リストを作成 */
	craete_patient_list(&list);

	/* コマンドファイルを実行 */
	interpret_command(fp, list);


	/* 患者リストを削除 */
	release_patient_list(list);
	/* コマンドファイルを閉じる */
	fclose(fp);
	return 0;
}


Output:
1
Exited: ExitFailure 1


Create a new paste based on this one


Comments: