Created
April 19, 2020 09:11
-
-
Save Roo4L/0e10e0dc5b661440c05da1861b9af943 to your computer and use it in GitHub Desktop.
lab4a
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdbool.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#define SIZE 3 | |
typedef struct Item item; | |
typedef struct database db; | |
typedef struct key_dimension kdim; | |
struct Item { | |
int key[2]; | |
char *info; | |
}; | |
struct key_dimension { | |
item *ip[SIZE]; | |
}; | |
struct database { | |
kdim dim[2]; | |
int len; | |
}; | |
char **get_command(void); | |
void add_item(int key1, int key2, char* info); | |
void delete_item(int key, int dimension); | |
int find_item(int key, int dimension); | |
void show_table(void); | |
int hash(int key, int iter); | |
char *getstr(void); | |
db table; // создание глобальной таблицы | |
item *deleted; // элемент - флаг удаления | |
int main(void) { | |
bool exit = false; | |
char **args; // аргументы функции | |
char *check; | |
int k1, k2, pos; | |
table.len = 0; | |
deleted = (item *)malloc(sizeof(item)); | |
printf("Welcome to Lab 4. The following options are now available: \n Add Item - add [key1] [key2] [info] \n Delete Item - delete [key] [dimension] \n Find Item - find [key] [dimension] \n List Items - show \n Exit - exit \n"); | |
while(!exit) { | |
printf("-->$ "); | |
args = get_command(); | |
if (args[1] != NULL){ | |
k1 = (int)strtol(args[1], &check, 10); | |
if (check-args[1] != strlen(args[1])){ | |
printf("Invalid arguments for key1. Please write your command using only 1 whitespace. \n"); | |
continue; | |
} | |
} | |
if (args[2] != NULL){ | |
k2 = (int)strtol(args[2], &check, 10); | |
if (check - args[2] != strlen(args[2])) { | |
printf("Invalid arguments for key2/dimension. Please write your command using only 1 whitespace. \n"); | |
continue; | |
} | |
} | |
if (strcmp(args[0], "add") == 0) { | |
add_item(k1, k2, args[3]); | |
} | |
else if (strcmp(args[0], "delete") == 0) { | |
delete_item(k1, k2); | |
} | |
else if (strcmp(args[0], "find") == 0) { | |
pos = find_item(k1, k2); | |
if (pos != -1) | |
printf("ITEM: \n key1: %d \n key2: %d \n info: %s \n", table.dim[k2-1].ip[pos]->key[0], table.dim[k2-1].ip[pos]->key[1], table.dim[k2-1].ip[pos]->info); | |
else | |
printf("Specific item not found. \n"); | |
} | |
else if (strcmp(args[0], "show") == 0) { | |
show_table(); | |
} | |
else if (strcmp(args[0], "exit") == 0) { | |
exit = true; | |
} | |
else { | |
perror("invalid command\n"); | |
} | |
} | |
return 0; | |
} | |
void add_item(int key1, int key2, char *info) { | |
if (table.len == SIZE) { | |
printf("Table is full. \n"); | |
return; | |
} | |
if (table.len != 0 && (find_item(key1, 1) != -1 || find_item(key2, 2) != -1)) { | |
printf("Item with the same key already exist. \n"); | |
return; | |
} | |
table.len++; | |
item *new; | |
new = (item *)calloc(1,sizeof(item)); | |
new->key[0] = key1; | |
new->key[1] = key2; | |
new->info = info; // keep in heap until the end! | |
int i = 0; | |
while(table.dim[0].ip[hash(key1, i)] != NULL && | |
table.dim[0].ip[hash(key1, i)] != deleted && | |
table.dim[0].ip[hash(key1, i)]->key[0] != key1) // lishii | |
i++; | |
table.dim[0].ip[hash(key1, i)] = new; | |
i = 0; | |
while(table.dim[1].ip[hash(key2, i)] != NULL && table.dim[1].ip[hash(key2, i)] != deleted && table.dim[1].ip[hash(key2, i)]->key[1] != key2) | |
i++; | |
table.dim[1].ip[hash(key2, i)] = new; | |
printf("Item added successfully. \n"); | |
} | |
int find_item(int key, int dimension) { | |
int i = 0; | |
while ((i < SIZE) && | |
(table.dim[dimension-1].ip[hash(key, i)] != NULL) && | |
(table.dim[dimension-1].ip[hash(key, i)]->key[dimension-1] != key)) { | |
i++; | |
} | |
if (i == SIZE || table.dim[dimension-1].ip[hash(key, i)] == NULL) | |
return -1; | |
else | |
return hash(key, i); | |
} | |
void delete_item(int key, int dimension) { | |
int pos = find_item(key, dimension); | |
if (pos == -1){ | |
printf("Specefic item doesn't exist. \n"); | |
} | |
else { | |
int pos2 = find_item(table.dim[dimension - 1].ip[pos]->key[dimension % 2], 3 - dimension); | |
free(table.dim[dimension-1].ip[pos]); | |
table.dim[dimension - 1].ip[pos] = deleted; | |
table.dim[dimension % 2].ip[pos2] = deleted; | |
table.len--; | |
printf("Item deleted successfully. \n"); | |
} | |
} | |
void show_table(void) { | |
int n = 0; | |
printf("%8s|%12s|%12s| Info \n", "#", "Key 1", "Key 2"); | |
for(int i = 0; i < SIZE; i++) { | |
if (table.dim[0].ip[i] != NULL && table.dim[0].ip[i] != deleted) { | |
printf("%8d|", n++); | |
printf("%12d|",table.dim[0].ip[i]->key[0]); | |
printf("%12d|",table.dim[0].ip[i]->key[1]); | |
if (strlen(table.dim[0].ip[i]->info) <= 50) | |
printf("%s\n",table.dim[0].ip[i]->info); | |
else | |
printf("%45s<...>\n",table.dim[0].ip[i]->info); | |
} | |
} | |
} | |
char **get_command(void) { | |
char *buf = getstr(); | |
char **args = (char **)calloc(4, sizeof(char *)); | |
int i = 0; | |
int len = strlen(buf); | |
bool end = false; | |
while (buf[i] == ' ' || buf[i] == '\t') { | |
if (i == len) | |
perror("no command was found"); | |
i++; | |
} | |
for (int j = 0; j < 3; j++) { | |
args[j] = buf + i; | |
while (buf[i] != ' ') { | |
if (i == len){ | |
end = true; | |
break; | |
} | |
i++; | |
} | |
if (end) | |
break; | |
buf[i++] = '\0'; | |
while (buf[i] == ' ' || buf[i] == '\t') { | |
if (i == len) { | |
end = true; | |
break; | |
} | |
i++; | |
} | |
if (end) | |
break; | |
} | |
if (!end) | |
args[3] = buf + i; | |
if (strcmp(args[0], "add") == 0 && args[3] == NULL) { | |
perror("invalid arguments for command \" add \"\n"); | |
args[0] = "error"; | |
} | |
else if (strcmp(args[0], "delete") == 0 && args[2] == NULL){ | |
perror("invalid arguments for command \" delete \"\n"); | |
args[0] = "error"; | |
} | |
else if (strcmp(args[0], "find") == 0 && args[2] == NULL){ | |
perror("invalid arguments for command \" find \"\n"); | |
args[0] = "error"; | |
} | |
return args; | |
} | |
int hash(int key, int iter) { | |
return ((abs(key) + iter) % SIZE); | |
} | |
char *getstr(void) { | |
char *ptr = (char *)calloc(1, sizeof(char *)); | |
char buf[81]; | |
int n, len = 0; | |
do { | |
n = scanf("%80[^\n]", buf); | |
if (n < 0) { | |
free(ptr); | |
ptr = NULL; | |
continue; | |
} | |
if (n == 0) { | |
scanf("%*c"); | |
} | |
else { | |
len += strlen(buf); | |
ptr = (char *)realloc(ptr, (len + 1) * sizeof(char)); | |
strcat(ptr, buf); | |
} | |
} while (n > 0); | |
return ptr; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment