מבוא לחישוב- הצעת פתרון לתרגיל בית 6 - 2010
מבוא לחישוב- הצעת פתרון לתרגיל בית 6 - 2010
מבוא לחישוב- הצעת פתרון לתרגיל בית 6 - 2010
c
#include #include #include #include <stdio.h> <stdlib.h> <string.h> "func.h"
int main(void) { database the_data_base; int exit_flag = 0; FILE *frp = fopen("conf.txt", "r"); output("", 1); char cmd[85]; databaseInit(&the_data_base); frp = fopen("conf.txt", "r"); if (frp == NULL) { printf("file conf.txt doesn't exist\n"); return 0; } while (fgets(cmd, 80, frp) != NULL && exit_flag == 0) { //on windows change to cmd[strlen(cmd) - 2] = '\0'; cmd[strlen(cmd) - 1] = '\0'; exit_flag = perform_cmd(&the_data_base, cmd); } output("", -1); fclose(frp); return 1; }
func.h
#ifndef HI #define HI // structs typedef struct { char ID[9]; char *name; int *salaries; int institutions_number; int *institutions; //array of index of institues the emploee belongs } emploee; typedef struct { char *name; int employees_num; emploee ** emploees; //points to array of pointers of emploees } institution; typedef struct { int institutions_number, emploees_number; institution ** institutions; //points to array of pointers of institutions emploee ** emploees; //points to array of pointers of all the emploees } database; // functions void output(char str[], int openCloseFlag); char digitToChar(int digit); void intToStr(char ** pstr, int num); int isValueInRange(int val, int min, int max); int isNumber(char ch); int isValidID(char str[]); int charToDigit(char ch); int strToInt(char str[]); int doesInstitueExist(database *the_data_base, char institueName[]); int doesEmploeeExist(database *the_data_base, char ID[]); int doesEmploeeExistInInstitue(database *the_data_base, char ID[], institution *inst); int insert_new_emploee(database *the_data_base, char empl_name[], char ID[]); int insert_new_institue(database *the_data_base, char inst_name[]); void connectInstitueToEmploee(database *the_data_base, int empl_index, int inst_index, int salary); void connectEmploeeToinstitue(database *the_data_base, int empl_index, int inst_index); int insert(database *the_data_base, char name[], char institue[], char ID[], char salary[]); int splitToSoolam(int **soolamPoses, char cmd_str[]); void free_words(char **words_array, int len); void print(database *the_data_base); void find(database* the_data_base, char ID[]); void freeDatabaseFromEmploee(database* the_data_base, int emp_index); void freeEmploee(database* the_data_base, emploee *empl); int delete(database* the_data_base, char ID[]); int whatIsTheIndexOfEmploeeInInstitue(database* the_data_base, emploee * empl, institution *inst); void freeAllDatabase(database* the_data_base); int perform_cmd(database* the_data_base, char cmd_str[]); #endif
func.c
#include #include #include #include <stdio.h> <stdlib.h> <string.h> "func.h"
void output(char str[], int openCloseFlag) { // input: a string and flag tells signing whether to close the file // output: writes str to the output file, opens the file if the flag is 1 closes it when it's -1 static FILE *fwp; if (openCloseFlag == -1) { fclose(fwp); return; } else if (openCloseFlag == 1) { fwp = fopen("out.txt", "w"); return; } //printf("%s\n", str); fputs(str, fwp); fputs("\r\n", fwp); } char digitToChar(int digit) { // input: a digit // output: returns the char of the digit return (char) (digit + 48); } void intToStr(char ** pstr, int num) { // input: pointer to string and an integer // output: changes pstr to point on a string representation of num int i = 0, len = 1; char temp; *pstr = (char*) realloc(*pstr, sizeof (char)); *pstr[0] = digitToChar(num % 10); num /= 10; while (num > 0) { len++; *pstr = (char*) realloc(*pstr, len * sizeof (char)); (*pstr)[len - 1] = digitToChar(num % 10); num /= 10; } *pstr = (char*) realloc(*pstr, (len + 1) * sizeof (char)); (*pstr)[len] = '\0'; len--; while (i < len) { temp = (*pstr)[i]; (*pstr)[i] = (*pstr)[len]; (*pstr)[len] = temp; i++; len--; } } int isValueInRange(int val, int min, int max) { // input: three integers named val, min and max // output: returns 1 if min<=val<=max and 0 otherwise return val >= min && val <= max; } int isNumber(char ch) { // input: a char // output: 1 if the char represents a number and 0 otherwise return isValueInRange((int) ch, 48, 57); }
int isValidID(char str[]) { // input: a string // output: 1 if the string represents a valid ID number and 0 otherwise int i; if (strlen(str) > 9) return 0; for (i = 0; i < 9; i++) { } return 1; if (!isNumber(str[i])) return 0;
int charToDigit(char ch) { // input: a char // output: returns the integer represented by the char return (int) ch - 48; } int strToInt(char str[]) { // input: a string // output: returns the integer represented by the string int i, len = strlen(str), sum = 0, weight = 1; for (i = len - 1; i >= 0; i--) { sum += (weight * charToDigit(str[i])); weight *= 10;
} return sum;
int doesInstitueExist(database *the_data_base, char institueName[]) { // input: database pointer and a string str int i = the_data_base->institutions_number; institution *inst; for (i--; i >= 0; i--) { inst = the_data_base->institutions[i]; if (strcmp(inst->name, institueName) == 0) { return i; } return -1; }
// output: the index of the institue in the_data_base institutions array whose name is str exists, -1 if no such institue exists
int doesEmploeeExist(database *the_data_base, char ID[]) { // input: database pointer and a string str // output: the index of the emploee in the_data_base emploees array whose ID is ID, -1 if no such institue exists int i = the_data_base->emploees_number; emploee *empl; for (i--; i >= 0; i--) { empl = the_data_base->emploees[i]; if (strcmp(empl->ID, ID) == 0) { } } return -1; } return i;
int doesEmploeeExistInInstitue(database *the_data_base, char ID[], institution *inst) { // input: database pointer, a string str and institution pointer // output: 1 if emploee with Id str wxist in institution int i = inst->employees_num; emploee *empl; for (i--; i >= 0; i--) { empl = inst->emploees[i]; if (strcmp(empl->ID, ID) == 0) { } } return 0; } int insert_new_emploee(database *the_data_base, char empl_name[], char ID[]) { // input: database pointer and emploee details: ID and name // output: inserts new emploee to the_data_base and returns the new length of the emploees array int new_len = the_data_base->emploees_number++;
the_data_base->emploees = (emploee**) realloc(the_data_base->emploees, the_data_base->emploees_number * sizeof (emploee*));
return 1;
the_data_base->emploees[new_len] = (emploee*) realloc(NULL, sizeof (emploee)); emploee *new_empl = the_data_base->emploees[new_len]; new_empl->name = empl_name; strcpy(new_empl->ID, ID); new_empl->institutions = NULL; new_empl->salaries = NULL; new_empl->institutions_number = 0; return new_len;
int insert_new_institue(database *the_data_base, char inst_name[]) { // input: database pointer and institue name // output: inserts new institue to the_data_base and returns the new length of the institues array int new_len = the_data_base->institutions_number++; the_data_base->institutions[new_len] = (institution*) realloc(NULL, sizeof (institution)); institution *new_inst = the_data_base->institutions[new_len]; new_inst->name = inst_name; new_inst->employees_num = 0; new_inst->emploees = NULL; return new_len; } void connectInstitueToEmploee(database *the_data_base, int empl_index, int inst_index, int salary) { //input: database pointer , institue and empolee indexes and the salary of the emploee in this institution //output: updates the emploee details that he belongs to the institue emploee *empl = the_data_base->emploees[empl_index]; int empl_inst_new_len = empl->institutions_number++; empl->institutions = (int*) realloc(empl->institutions, (empl_inst_new_len + 1) * sizeof (int)); empl->institutions[empl_inst_new_len] = inst_index; empl->salaries = (int*) realloc(empl->salaries, (empl_inst_new_len + 1) * sizeof (int)); empl->salaries[inst_index] = salary; } void connectEmploeeToinstitue(database *the_data_base, int empl_index, int inst_index) { // input: database pointer and institue and empolee indexes // output: updates the institue details that the emploee belongs to it institution *inst = the_data_base->institutions[inst_index]; int inst_empl_new_len = inst->employees_num++; inst->emploees = (emploee**) realloc(inst->emploees, (inst_empl_new_len + 1) * sizeof (emploee*)); inst->emploees[inst_empl_new_len] = the_data_base->emploees[empl_index]; }
the_data_base->institutions = (institution**) realloc(the_data_base->institutions, the_data_base->institutions_number * sizeof (institution*));
int insert(database *the_data_base, char institue[], char name[], char ID[], char salary[]) { // input: the data base p[ointer and details of new emploee: his salary, ID, institue's name, // output: 1 when insertion was performed successfully, 0 otherwise if (!isValidID(ID)) { output("error", 0); return 0; } institution *current_inst; emploee *current_empl; int institution_index, emploee_index; int is_new_institue = doesInstitueExist(the_data_base, institue); int is_new_empl = doesEmploeeExist(the_data_base, ID); if (is_new_institue != -1) { institution_index = is_new_institue; if (doesEmploeeExistInInstitue(the_data_base, ID, the_data_base->institutions[institution_index]) ) { output("already in database", 0); return 0; } } else { institution_index = insert_new_institue(the_data_base, institue); } if (is_new_empl != -1) { emploee_index = is_new_empl; free(name); } else { emploee_index = insert_new_emploee(the_data_base, name, ID); } free(ID); current_inst = (the_data_base->institutions)[institution_index]; current_empl = (the_data_base->emploees)[emploee_index]; connectInstitueToEmploee(the_data_base, emploee_index, institution_index, strToInt(salary)); connectEmploeeToinstitue(the_data_base, emploee_index, institution_index); return 1; } int splitToSoolam(int **soolamPoses, char cmd_str[]) { // input: pointer of integer and a command string // output: makes the pointer to an array of integers denoting the place of the next Sollam in cmd_str and returns its length int i, len = strlen(cmd_str), soolam_num = 0; for (i = 0; i < len; i++) { if (cmd_str[i] == '#') { soolam_num++; *soolamPoses = (int*) realloc(*soolamPoses, soolam_num * sizeof (int)); (*soolamPoses)[soolam_num - 1] = i;
} } return soolam_num; }
void free_words(char **words_array, int len) { // input: dynamic words array and its length // output: frees the array and the words int i; for (i = 0; i < len; i++) { free(words_array[i]); } free(words_array);
void print(database *the_data_base) { // input: the database pointer // output: prints the database int empty = 1; if (the_data_base->institutions_number == 0 || the_data_base->emploees_number == 0) { output("empty database", 0); return; } int i, j, emploees_length; institution *loop_institution; emploee *loop_emploee; for (i = 0; i < the_data_base->institutions_number; i++) { loop_institution = the_data_base->institutions[i]; output(loop_institution->name, 0); emploees_length = loop_institution->employees_num; if (emploees_length == 0) { output("**********", 0); output("no workers", 0); } else { empty = 0; for (j = 0; j < emploees_length; j++) { loop_emploee = loop_institution->emploees[j]; output("**********", 0); output(loop_emploee->name, 0); output(loop_emploee->ID, 0); char *tmp = NULL; intToStr(&tmp, loop_emploee->salaries[i]); output(tmp, 0); free(tmp); } } } if (empty) { } } void find(database* the_data_base, char ID[]) { // input: database pointer and an ID string // output: prints the institues where the emploee with the id ID works (or "not exist" if there are no results) int empl_index = doesEmploeeExist(the_data_base, ID); if (empl_index == -1) { output("not exist", 0); } else { emploee *empl_pointer = the_data_base->emploees[empl_index]; int inst_num = empl_pointer->institutions_number, i; for (i = 0; i < inst_num; i++) { output(the_data_base->institutions[empl_pointer->institutions[i]]->name, 0); } } void freeDatabaseFromEmploee(database* the_data_base, int emp_index) { //input: database pointer and an emploee index //output: free the memory of the database->emploees from the emploee int last_emp = --(the_data_base->emploees_number); the_data_base->emploees[emp_index] = the_data_base->emploees[last_emp]; the_data_base->emploees = (emploee**) realloc(the_data_base->emploees, last_emp * sizeof (emploee*)); } } output("empty database", 0);
void freeEmploee(database* the_data_base, emploee *empl) { // input: database pointer and an emploee pointer // output: free the memory of the emploee free(empl->salaries); free(empl->institutions); free(empl->name); free(empl); } int delete(database* the_data_base, char ID[]) { // input: database pointer and an ID string //output: deletes the emploee from the database and returns 1 or 0 if no such emploee exists in database int empl_index = doesEmploeeExist(the_data_base, ID); if (empl_index == -1) { return 0; } else { emploee *empl_pointer = the_data_base->emploees[empl_index]; int inst_num = empl_pointer->institutions_number, i, j; for (i = 0; i < inst_num; i++) { //frees the emploee pointer in the institutions institution *inst = the_data_base->institutions[empl_pointer->institutions[i]]; int emp_index = whatIsTheIndexOfEmploeeInInstitue(the_data_base, empl_pointer, inst); int last_emp_index = --(inst->employees_num); inst->emploees[emp_index] = inst->emploees[last_emp_index]; } // free the database and the emploee itself freeDatabaseFromEmploee(the_data_base, empl_index); freeEmploee(the_data_base, empl_pointer); return 1;
inst->emploees = (emploee**) realloc(inst->emploees, last_emp_index * sizeof (emploee*));
} }
int whatIsTheIndexOfEmploeeInInstitue(database* the_data_base, emploee * empl, institution *inst) { // input: database pointer, and institution and emploee pointers // output: the index of the emploee in the array of emploees of the institution int i, emp_num = inst->employees_num; for (i = 0; i < emp_num; i++) { if (empl == inst->emploees[i]) return i; } } void freeAllDatabase(database* the_data_base) { // input: database pointer // output: frees the database int len = the_data_base->institutions_number, i, len2, j; institution *inst; emploee *empl; //institutions for (i = 0; i < len; i++) { inst = the_data_base->institutions[i]; free(inst->name); free(inst->emploees); free(inst); } free(the_data_base->institutions); //emploees len = the_data_base->emploees_number; for (i = 0; i < len; i++) { empl = the_data_base->emploees[i]; free(empl->name); free(empl->salaries); free(empl->institutions); } free(the_data_base->emploees); }
int perform_cmd(database* the_data_base, char cmd_str[]) { // input:database pointer and command line of the user // output: the function performs the command and returns 1 if he command is exit and 0 otherwise //spliting the command by Soolam int i, *soolam_poses = NULL; int soolam_num = splitToSoolam(&soolam_poses, cmd_str); char **words_splited = NULL; //array of strings int last_index = 0, loop_word_len; for (i = 0; i < soolam_num; i++) { loop_word_len = soolam_poses[i] - last_index; words_splited = (char* *) realloc(words_splited, (i + 1) * sizeof (char*)); words_splited[i] = (char*) realloc(NULL, (loop_word_len + 2) * sizeof (char)); strncpy(words_splited[i], (cmd_str + last_index), loop_word_len); (words_splited[i])[loop_word_len] = '\0'; last_index = soolam_poses[i] + 1; } //last word loop_word_len = strlen(cmd_str) - last_index; words_splited = (char* *) realloc(words_splited, (i + 1) * sizeof (char*)); words_splited[i] = (char*) realloc(NULL, (loop_word_len + 2) * sizeof (char)); strncpy(words_splited[i], cmd_str + last_index, loop_word_len + 2); //checking command char *cmd = words_splited[0]; //printf("\n%s\n", cmd); //debug if (strcmp(cmd, "INSERT") == 0) {
//printf("%s %s %s %s asdfasdasd\n", words_splited[1], words_splited[2], words_splited[3], words_splited[4]); //debug
} else if
if (insert(the_data_base, words_splited[1], words_splited[2], words_splited[3], words_splited[4])) { free(words_splited[4]); //ID free(words_splited); output("success", 0); } else { free_words(words_splited, i + 1); } (strcmp(cmd, "FIND") == 0 && i == 1) { find(the_data_base, words_splited[1]); free_words(words_splited, 2); (strcmp(cmd, "PRINT") == 0 && i == 0) { print(the_data_base); free_words(words_splited, 1); (strcmp(cmd, "DELETE") == 0 && i == 1) { if (delete(the_data_base, words_splited[1])) output("deleted", 0); else output("not exist", 0); free_words(words_splited, 1); (strcmp(cmd, "EXIT") == 0 && i == 0) { free_words(words_splited, 1); freeAllDatabase(the_data_base); return 1; free_words(words_splited, i + 1); output("WRONG INPUT", 0);
} else { } return 0;
void databaseInit(database* the_data_base) { // input: database pointer // output: initialize the first value of the database the_data_base->institutions = NULL; the_data_base->emploees = NULL; the_data_base->institutions_number = 0; the_data_base->emploees_number = 0; } Makefile
a.out: func.o main.o gcc func.o main.o functions.o: func.c gcc -c func.c main.o: main.c gcc -c main.c