#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*プロトタイプ宣言*/
struct date{ //日付の構造体
int y;
int m;
int d;
};
struct profile{ //名簿データの構造体
int id;
char name[70];
struct date birthday;
char home[70];
char *comment;
struct profile *next;
};
void subst( char *s, char f, char t) //入力した文字列の改行をNULLに替える
{
while(*s != '\0'){
if(*s == f){
*s = t;
}
s++;
}
}
void split(char *s, char *s2[], char t, int n) //アドレスをとる
{
int i = 0;
s2[i++] = s;
while(*s != '\0' && i < n){
if(*s == t){
*s = '\0';
s2[i++] = s+1;
}
s++;
}
}
void add_profile(struct profile *p, char *ret[], int i){ //データを格納
char *date[3];
p[i].id = (int)atoi(ret[0]);
sprintf(p[i].name, "%s", ret[1]);
sprintf(p[i].home, "%s", ret[3]);
p[i].comment = (char *)malloc(strlen(ret[4]) + 1);
strcpy( p[i].comment, ret[4]);
split( ret[2], date, '-', 3);
p[i].birthday.y = (int)atoi(date[0]);
p[i].birthday.m = (int)atoi(date[1]);
p[i].birthday.d = (int)atoi(date[2]);
}
struct profile profile_data[10000]; //グローバル変数
int nprofiles = 0;
int update = 0;
void read_profile(const char *s){ //%Rコマンド
FILE *fp;
char s2[2048];
char *ret[5];
if ((fp = fopen( s, "r")) == NULL){
fprintf(stderr,"file open error\n");
exit(1);
}
while(fgets( s2, sizeof(s2)-1, fp) != NULL){
subst( s2, '\n', '\0');
split(s2, ret, ',', 5);
add_profile(profile_data , ret, nprofiles++);
}
fclose(fp);
}
void write_profile(const char *s){ //%Wコマンド
FILE *fp;
int i = 0;
if((fp = fopen(s,"w")) == NULL){
fprintf(stderr,"file open error\n");
exit(1);
}
while(i < nprofiles){
fprintf( fp, "%d,%s,%d-%d-%d,%s,%s\n",
profile_data[i].id, profile_data[i].name,
profile_data[i].birthday.y, profile_data[i].birthday.m, profile_data[i].birthday.d,
profile_data[i].home, profile_data[i].comment);
i++;
}
fclose(fp);
}
void found_profile(struct profile *p, const char *word){
int i;
char str[2048];
for(i = 0; i < nprofiles; i++, p = p + 1){
sprintf(str, "%d,%s,%d-%d-%d,%s,%s", p->id, p->name, p->birthday.y,
p->birthday.m, p->birthday.d, p->home, p->comment);
if( strstr(str, word) != NULL){
printf("\nID\t: %d\n", p->id);
printf("Name\t: %s\n", p->name);
printf("Date\t: %d/%02d/%02d\n",
p->birthday.y, p->birthday.m, p->birthday.d);
printf("Addr\t: %s\n", p->home);
printf("Memo\t: %s\n", p->comment);
}
}
}
void print_profile(const char *s){ //%Pによってメモリ中にあるデータを出力
long n = atol(s), i;
struct profile *p;
int d;
if (n > 0) {
d = 1;
p = profile_data;
} else if (n < 0){
n = -n;
d = 1;
p = profile_data + nprofiles - n;
} else if (n == 0){
d = 1;
p = profile_data;
n = nprofiles;
}
if ( n > nprofiles)
n = nprofiles;
for (i = 0; i < n; i++, p = p + d) {
printf("\nID\t: %d\n", p->id);
printf("Name\t: %s\n", p->name);
printf("Date\t: %d/%02d/%02d\n",
p->birthday.y, p->birthday.m, p->birthday.d);
printf("Addr\t: %s\n", p->home);
printf("Memo\t: %s\n", p->comment);
}
}
int compare_id(struct profile *a, struct profile *b){
return ( a->id - b->id );
}
int compare_name(struct profile *a, struct profile *b){
return strcmp( a->name, b->name );
}
int compare_date(struct profile *a, struct profile *b){
if( a->birthday.y != b->birthday.y )
return ( a->birthday.y - b->birthday.y );
if( a->birthday.m != b->birthday.m )
return ( a->birthday.m - b->birthday.m);
return ( a->birthday.d - b->birthday.d );
}
int compare_home(struct profile* a, struct profile* b){
return strcmp( a->home, b->home );
}
void command_sort(int n){
struct profile kari = {0};
int (*comp)(struct profile *a,struct profile *b);
int i, j;
switch(n){
case 1:
comp = compare_id;
break;
case 2:
comp = compare_name;
break;
case 3:
comp = compare_date;
break;
case 4:
comp = compare_home;
break;
}
for(i = 0; i < nprofiles; i++){
for(j = nprofiles - 1; j > i; j--){
if((*comp)( &profile_data[i], &profile_data[j]) > 0 ){
kari = profile_data[i];
profile_data[i] = profile_data[j];
profile_data[j] = kari;
}
}
}
}
void delete_profile(int x){
struct profile *p = profile_data[0].next;
struct profile *head = &profile_data[0];
while(p != NULL){
if(p->id == x){
head->next = p->next;
p->next = NULL;
break;
}
head = p;
p = p->next;
printf("%d",p->id);
}
if(p == NULL){
printf("not found ID:%d\n",x);
}
}
int parse_input(FILE *fp){ //文字列を入力、%の分岐、データを分解・格納
char line[2048] = {0};
char *ret[5];
int i = 1;
char quit;
printf("? ");
if (fgets(line, sizeof(line)-1, fp) == NULL)
return 0;
subst(line, '\n', '\0');
if(line[0] == '%'){
switch( line[1] ){
case 'Q':
if(update == 1){
printf("data is updated. exit really? ( y / n ) ");
if((scanf( "%c", &quit)) == 'y' ){
exit(0);
}
else{
break;
}
}
break;
case 'C':
printf(" %d profile(s).\n", nprofiles);
break;
case 'P':
print_profile(line + 2);
break;
case 'R':
read_profile(line + 3);
update = 1;
break;
case 'W':
write_profile(line + 3);
update = 0;
break;
case 'F':
found_profile(profile_data, line + 3);
break;
case 'S':
command_sort(atoi(line + 3));
update = 1;
break;
case 'D':
delete_profile(atoi(line + 3));
update = 1;
break;
}
}
else {
split(line, ret, ',', 5);
add_profile(profile_data , ret, nprofiles++);
}
return i;
}
int main(){
printf("ID,学校名,設立年月日(年-月-日),所在地,備考データ\n");
while( parse_input(stdin) ); //無限ループ
update = 1;
return 0;
}