Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PATH_MAX 256
/* define a structure for an entry in an test question*/
typedef struct entry_s{
char* question;
char* a;
char* b;
char* c;
char* d;
char* answer;
struct entry_s* next;/* pointer to next element*/
struct entry_s* prev;/* pointer to previous element*/
}entry_t;
entry_t* head=NULL;/* always points at first element*/
entry_t* tail=NULL;/* always points at last element*/
int size=0;
void destroy_test(){
entry_t* tmp=head;
entry_t* del=head;
while(tmp){
del=tmp;
tmp=tmp->next;
free(del->answer);
free(del->question);
free(del->c);
free(del->d);
free(del->b);
free(del->a);
free(del);
}
head=NULL;
tail=NULL;
size=0;
}
void add_entry(char* question,char* a,char* b,char* c,char* d,char* answer){
entry_t* fresh=(entry_t*)malloc(sizeof(entry_t));/* dynamically allocate data*/
fresh->answer=answer;
fresh->question=question;
fresh->c=c;
fresh->d=d;
fresh->b=b;
fresh->a=a;
/* link the variable in*/
if(head==NULL){/* insert into empty list*/
fresh->next=NULL;
fresh->prev=NULL;
head=tail=fresh;
}
else{/* insert at tail in non-empty list*/
fresh->next=NULL;
tail->next=fresh;
fresh->prev=tail;
tail=fresh;
}
size++;
}
// THERE ARE TWO ERRORS WHEN IN THE LOAD FUNTION - when run in windows...
void load_entry(char* tagline){
entry_t* fresh=(entry_t*)malloc(sizeof(entry_t));
char parameter[255];
unsigned int i=0,j=0;
unsigned int mod=0;
for(i=0;i<strlen(tagline);i++){
if(tagline[i]!=';'){/* build up the parameter*/
parameter[j]=tagline[i];
j++;
}
else{
parameter[j]=0;
j=0;
switch(mod){/* cycle through parameters*/
case 0: fresh->question=(char*)malloc((strlen(parameter)+1)*sizeof(char));
strcpy(fresh->question,parameter);break;
case 1: fresh->a=(char*)malloc((strlen(parameter)+1)*sizeof(char));
strcpy(fresh->a,parameter);break;
case 2: fresh->b=(char*)malloc((strlen(parameter)+1)*sizeof(char));
strcpy(fresh->b,parameter);break;
case 3: fresh->c=(char*)malloc((strlen(parameter)+1)*sizeof(char));
strcpy(fresh->c,parameter);break;
case 4: fresh->d=(char*)malloc((strlen(parameter)+1)*sizeof(char));
strcpy(fresh->d,parameter);break;
case 5: fresh->answer=(char*)malloc((strlen(parameter)+1)*sizeof(char));
strcpy(fresh->answer,parameter);break;
}
mod++;
}
}
/* link the variable in*/
if(head==NULL){/* insert into empty list*/
fresh->next=NULL;
fresh->prev=NULL;
head=tail=fresh;
}
else{/* insert at tail in non-empty list*/
fresh->next=NULL;
tail->next=fresh;
fresh->prev=tail;
tail=fresh;
}
size++;
}
void load_test(char* filename){
FILE* file=NULL;
char buffer[255];
file=fopen(filename,"r");/* try to open for read*/
if(file){
while(fgets(buffer,255,file))/* read a line of 80 chars*/
load_entry(buffer);/* store entry in test question*/
fclose(file);
printf("\nTest sucessfully loaded!\n\n");
}
else
printf("\a\nFile not found!\n\n");
}
void save_test(char* filename){
FILE* file=NULL;
char choice;
entry_t* show=head;
if(head==NULL){
printf("\nYour test question is currently empty!\n\n");
return;
}
file=fopen(filename,"r");/* check for file exist*/
if(file){
fclose(file);
printf("\a\nFile already exists!");
printf("\n<O>verwrite/<A>ppend/<C>lose? ");
scanf("%c",&choice);
fflush(stdin);
switch(choice){
case 'o':
case 'O':
file=fopen(filename,"w");
break;
case 'a':
case 'A':
file=fopen(filename,"a");
break;
case 'c':
case 'C':
return;
break;
default:
printf("\nIllegal command!\n\n");
return;
break;
}
}
else{
file=fopen(filename,"w");/* open for write*/
}
if(file){
while(show!=NULL){/* cycle through list, write one entry per line, each parameter seperated by semicolon*/
//fprintf(file,"Question [%.2d]: %s\n\n \t\tA.) %s\n \t\tB.) %s\n \t\tC.) %s\n \t\tD.) %s\n \t\tAnswer: %s\n\n",id,show->question,show->a,show->b,show->c,show->d,show->answer);
fprintf(file,"%s %s %s %s %s %s\n",show->question,show->a,show->b,show->c,show->d,show->answer);
show=show->next;
}
if(fclose(file))
printf("\a\nError during write operation!\n\n");
else
printf("\nWrite operation completed successfully!\n\n");
}
else
printf("\a\nError during write operation!\n\n");
}
void print_test(int sort_criteria){
entry_t* show;
int i=1;
if(head){
show=head;
printf("\nYour test question currently has %d entries:\n\n",size);
while(show){
switch(sort_criteria){
case 1:/*question*/
printf("Question [%.2d]: %s\n \t\tA.) %s\n \t\tB.) %s\n \t\tC.) %s\n \t\tD.) %s\n \t\tAnswer: %s\n\n",i,show->question,show->a,show->b,show->c,show->d,show->answer);
break;
}
show=show->next;
i++;
}
printf("\n");
}
else
printf("\nYour test question is currently empty!\n\n");
}
int* search_entry(char* search,int search_criteria,int* num_matches){
entry_t* found=head;
int i=0,pos=1;
char* str_search=NULL;
int* matches=NULL;
*num_matches=0;
/* count how many times we have a match*/
while(found){
switch(search_criteria){
case 1:/* question*/
str_search=found->question;
break;
case 2:/* a*/
str_search=found->a;
break;
case 3:/* b*/
str_search=found->b;
break;
case 4:/* c*/
str_search=found->c;
break;
case 5:/* d*/
str_search=found->d;
break;
case 6:/* answer*/
str_search=found->answer;
break;
}
if(!strcmp(str_search,search)){
(*num_matches)++;
if(*num_matches==1){/* dynamically allocate memory*/
matches=(int*)malloc(*num_matches*sizeof(int));
matches[*num_matches-1]=pos;
}
if(*num_matches>1){/* increase memory block according to num_matches*/
matches=(int*)realloc(matches,*num_matches*sizeof(int));
matches[*num_matches-1]=pos;
}
}
found=found->next;
pos++;
}
return matches;/* return array with matching positions or NULL*/
}
int delete_entry(int index){
entry_t* del=head;
entry_t* left;
entry_t* right;
int pos=1;
while(del){
if(pos==index){
left=del->prev;/* store left side*/
right=del->next;/* store right side*/
if(left)/* close the gap*/
left->next=right;
if(right)
right->prev=left;
if(del==head)/* if we have to touch the head*/
head=right;
if(del==tail)/* if we have to touch the tail*/
tail=left;
free(del->answer);/* free dynamically allocated memory*/
free(del->question);
free(del->c);
free(del->d);
free(del->b);
free(del->a);
free(del);/* free the pointer itself*/
size--;/* decrease size*/
return 1;
}
else{
del=del->next;
pos++;
}
}
return 0;
}
int main(int argc,char** argv){
int i=0,index=0,num_matches=0;
//int i=0,index=0,num_matches=0,PATH_MAX=0;
char buffer[80]={0},filename[PATH_MAX]={0};
char *question=NULL,*a=NULL,*b=NULL,*c=NULL,*d=NULL,*answer=NULL;
int *matches=NULL;
unsigned char choice=0,sort_criteria=1,search_criteria=0;
do{
printf("*** TOMS (Today's Operating Media Services) ***\n\n");
printf("[1] LOAD DATA\n[2] ADD QUESTION\n[3] DELETE QUESTION\n[4] EDIT QUESTION\n[5] PRINT QUESTIONS\n[6] SAVE\n[7] QUIT\n");
scanf("%c",&choice);
choice-=48;
fflush(stdin);
switch(choice){
case 1:
//flush(stdin);
destroy_test();
load_test("questions.dat");
break;
case 2://
//fflush(stdin);
printf("Please enter new record:\n");
//printf("\nQuestion: ");
//fgets(buffer, sizeof(buffer), stdin);
//question=(char*)malloc((strlen(buffer)+1)*sizeof(char));
//strcpy(question,buffer);
printf("\nQuestion: ");
fgets(buffer, sizeof(buffer), stdin);//// needed to change the add the 2 parameters to fgets
question=(char*)malloc((strlen(buffer)+1)*sizeof(char));
strcpy(question,buffer);
printf("\nA: ");
fgets(buffer, sizeof(buffer), stdin);//// needed to change the add the 2 parameters to fgets
a=(char*)malloc((strlen(buffer)+1)*sizeof(char));
strcpy(a,buffer);
printf("\nB: ");
fgets(buffer, sizeof(buffer), stdin);
b=(char*)malloc((strlen(buffer)+1)*sizeof(char));
strcpy(b,buffer);
printf("\nC: ");
fgets(buffer, sizeof(buffer), stdin);
c=(char*)malloc((strlen(buffer)+1)*sizeof(char));
strcpy(c,buffer);
printf("\nD: ");
fgets(buffer, sizeof(buffer), stdin);
d=(char*)malloc((strlen(buffer)+1)*sizeof(char));
strcpy(d,buffer);
printf("\nAnswer: ");
fgets(buffer, sizeof(buffer), stdin);
answer=(char*)malloc((strlen(buffer)+1)*sizeof(char));
strcpy(answer,buffer);
add_entry(question,a,b,c,d,answer);
printf("\n");
break;
case 3://
fflush(stdin);
printf("\nEnter index: ");
fgets(buffer, sizeof(buffer), stdin);
index=atoi(buffer);
if(delete_entry(index))
printf("\nEntry deleted!\n\n");
else
printf("\a\nWrong index!\n\n");
break;
case 4://
fflush(stdin);
printf("\nEnter search criteria\n(1=question,2=a,3=b,4=c,5=d,6=answer): ");
scanf("%c",&search_criteria);
search_criteria-=48;
fflush(stdin);
if(search_criteria>=1&&search_criteria<=6){
printf("\nEnter search value: ");
fgets(buffer, sizeof(buffer), stdin);
matches=search_entry(buffer,search_criteria,&num_matches);
if(matches==NULL)
printf("\nNo matching entry!\n\n");
else{
printf("\nEntry found at position(s) ");
for(i=0;i<num_matches;i++)
if(i==num_matches-1)
printf("%d!\n\n",matches[i]);
else
printf("%d,",matches[i]);
free(matches);/* free dynamically allocated data*/
}
}
else
printf("\a\nWrong search criteria!\n\n");
break;
case 5://
print_test(sort_criteria);
break;
//case sort:
//fflush(stdin);
//printf("\nEnter sort criteria\n(1=question,2=a,3=b,4=c,5=d,6=answer): ");
//scanf("%c",&sort_criteria);
//sort_criteria-=48;
//fflush(stdin);
//if(sort_criteria>=1&&sort_criteria<=6){
//if(sort_test(sort_criteria))
//printf("\nTest Questions sorted!\n\n");
//else
//printf("\nNothing to sort!\n\n");
//}
//else
//printf("\a\nWrong sort criteria!\n\n");
//break;
case 6://
//fflush(stdin);
//void option5 ( void )
{
save_test("questions.dat");
}
break;
case 7://
destroy_test();
break;
default:
printf("\a\nIllegal command!\n\n");
break;
}
}while(choice!=7);
return 0;
}