Skip to content

Instantly share code, notes, and snippets.

@Roo4L
Created April 19, 2020 09:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Roo4L/0e10e0dc5b661440c05da1861b9af943 to your computer and use it in GitHub Desktop.
Save Roo4L/0e10e0dc5b661440c05da1861b9af943 to your computer and use it in GitHub Desktop.
lab4a
#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