Skip to content

Instantly share code, notes, and snippets.

@LionZXY
Last active February 18, 2019 00:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LionZXY/784a1e190c602dd3fcc865ea64f130ad to your computer and use it in GitHub Desktop.
Save LionZXY/784a1e190c602dd3fcc865ea64f130ad to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <string.h>
#define __MAX_SIZE 256 // Директива прекомплятора. Что это за страшные слова? Смотри:
/**
* Компилятор си он умный. Перед тем как компилировать код он проходиться по нему и выполняет специальный код (да-да, язык внутри языка)
* В данном случае это означает, что везде где написанно __MAX_SIZE компилятор заменит на 256
*/
typedef struct Book book; // Обьявляем что структура впринципе существует.
struct Book // Уже подробно описываем её и рассказываем что там внутри
{
char ISBN[14]; // Строка (массив символов). Массив максимум 14 элементов - это означает, что ничего больше 14 символов мы положить не можем
// => Строка "1234567890123" поместиться, а вот уже "12345678901234" нет (13 символов + ноль в конце)
char Author[__MAX_SIZE]; // Это строка (автор, в данном случае). Благодаря доброму (а как иначе, он же няшка) компилятору эта строчка будет выглядеть так:
// char Author[256];
char Title[__MAX_SIZE]; // Строка (название книги)
// char Title[256];
int All; // Целое число. Всего сколько книг
int Free; // Сколько книг доступно
};
typedef struct Student student; // Обьявляем что структура впринципе существует.
struct Student // Уже подробно описываем её и рассказываем что там внутри
{
char ID[7]; // ОГО! Тут уже ограничение на 7 символов! Вот это уже серьезно. Значит "1234567" уже не вместиться
char FamilyName[__MAX_SIZE];
// Ну ты уже понял, да?
char Name[__MAX_SIZE];
char FatherName[__MAX_SIZE];
char Faculty[3]; // Тут максимум может вместиться "ИУ". "ИБМ" недостойны места в этой божественной программе.
char Specialist[__MAX_SIZE];
};
typedef struct User user; // Ну ты уже понял, да?
struct User // Ну ты уже понял, да?
{
char Username[__MAX_SIZE];
char Password[__MAX_SIZE];
int ADbook; // Это целочисленное значение. В нем содержиться права на чтение и запись книги (доступ к меню книг) //TODO узнать значение
int ADstudent; // Это целочисленное значение. В нем содержиться права на чтение и запись студента (доступ к меню студента) //TODO узнать значение
};
/**
* Переменные - это одна из самых важных частей в програмировании
* Это область в памяти, куда можно что-то складывать и доставать.
* От того ЧЕГО туда можно складывать зависит первая часть строки (book), а от того как переменная будет называться, вторая (Books).
* Итого, строка:
* bool Books;
* Обьявит переменную book с именем Books. Мы можем обращаться к этой переменной, например, так: cout << Books;
* Однако, ты уже заметил, что там еще есть [] вконце. Это значит, что мы обьявили массив. Это значит МНОГО переменных. Кхм, не много, а ровно __MAX_SIZE (помнишь я рассказывал тебе про прекомпилятор?)
* Обращаться к такой переменной можно, например, так: Books[1] - обращение ко второму элементу массива
* Этому
* Books: | BOOK1 | BOOK2 | BOOK3 | ...
**/
book Books[__MAX_SIZE]; // Вот это уже интересно. Это ГЛОБАЛЬНАЯ ПЕРЕМЕННАЯ! Как только твоя программа загрузиться (Не запуститься! Загрузиться (до вызова метода int main()) это значение будет проинициализированна (выделиться память под неё)
student Students[__MAX_SIZE];
user Users[__MAX_SIZE];
int check;
//^ Ну все выше ты понял, да?
void swap(int *, int *);
void strswap(char a[], char b[]);
//Part: Book
/**
* Все методы про книги. Тут есть один подвох. В C нельзя делать методы с одинаковыми именами (иначе как компилятор поймет чего ты хочешь вызвать?)
* Поэтому имена такие длинные.
* Существует два типа называния переменных CamelCase (каждое слово с большой буквы) и вот эта херовина: part_1_book
* Оба варианта заслуживают признания, но лучше использовать какой-то один
**/
void part_1_book();
/**
* Мы впервые встретились с указателем!
* Итак, указатель - эта такая штука, которая УКАЗЫВАЕТ на область памяти в которой храниться переменная, а не на саму переменную (в отличии от переменной)
* int * test1; <- Указатель!
* int test2; <- Переменная!
* Еще по указателю не обязательно может быть одна переменная, может быть и больше.
* САМОЕ ГЛАВНОЕ ЗАПОМНИТЬ! Указатель УКАЗЫВАЕТ на область памяти
*/
int readBook(const char *filename);
// WARNING! В этот метод можно положить строку меньше 14 символов
int comparingISBN(char a[14]);
void addingNewBook(const char *filename);
void searchingBook(const char *filename);
void deletingBook(const char *filename);
void sortingBook(const char *filename);
//Part: Student
// Ну ты понял, да?
void part_1_student();
int readStudent(const char *filename);
int comparingID(char a[7]);
void addingNewStudent(const char *filename);
void deletingStudent(const char *filename);
void editingStudent(const char *filename);
void searchingStudent(const char *filename);
//Part: User
void part_2_user();
int readUser(const char *filename);
int checkUser(const char *filename);
// Главная точка входа в программу!
int main(int argc /* количество аргументов командной строки */,
char **argv /* Очень запутанная структура. Указатель на указатели (на область памяти где храняться указатели) */) {
check = checkUser("user.csv");
if (check == -1) {
printf("WRONG!!!");
} else
part_2_user();
return 0;
}
void part_1_book() {
int n = readBook("book.csv");
if (n == -1) {
printf("ERROR #1: empty file");
} else {
int x;
printf("MENU BOOK:");
printf("\n0) Main Menu");
printf("\n1) Add");
printf("\n2) Delete");
printf("\n3) Search");
printf("\n4) Show");
printf("\n5) Esc");
printf("\nYou want:");
scanf("%d", &x); // Вводим x (& - значит получить указатель на переменную)
fflush(stdin);
switch (x) {
case 0: {
part_2_user();
break;
}
case 1: {
if (Users[check].ADbook == 1) {
addingNewBook("book.csv");
break;
} else {
printf("You can't\n");
part_2_user();
}
}
case 2: {
if (Users[check].ADbook == 1) {
deletingBook("book.csv");
break;
} else {
printf("You can't\n");
part_2_user();
}
}
case 3: {
searchingBook("book.csv");
break;
}
case 4: {
sortingBook("book.csv");
break;
}
case 5: {
break;
}
default:;
}
}
}
void part_1_student() {
int n = readStudent("student.csv");
if (n == -1) {
printf("ERROR #1: empty file");
} else {
int x;
printf("MENU STUDENT:");
printf("\n0) Main Menu");
printf("\n1) Add");
printf("\n2) Delete");
printf("\n3) Edit");
printf("\n4) Search");
printf("\n5) Esc");
printf("\nYou want:");
scanf("%d", &x);
fflush(stdin);
switch (x) {
case 0: {
part_2_user();
break;
}
case 1: {
if (Users[check].ADstudent == 1) {
addingNewStudent("student.csv");
break;
} else {
printf("You can't\n");
part_2_user();
}
}
case 2: {
if (Users[check].ADstudent == 1) {
deletingStudent("student.csv");
break;
} else {
printf("You can't\n");
part_2_user();
}
}
case 4: {
searchingStudent("student.csv");
break;
}
case 3: {
if (Users[check].ADstudent == 1) {
editingStudent("student.csv");
break;
} else {
printf("You can't\n");
part_2_user();
}
}
case 5: {
break;
}
default:;
}
}
}
void part_2_user() {
if (check != -1) {
int n = readUser("user.csv");
if (n == -1) {
printf("ERROR #1: empty file");
} else {
int x;
printf("MENU:");
printf("\n1) Book");
printf("\n2) Student");
printf("\nYou want:");
scanf("%d", &x);
fflush(stdin);
switch (x) {
case 1: {
part_1_book();
break;
}
case 2: {
part_1_student();
break;
}
default:;
}
}
} else
printf("WRONG");
}
int readBook(const char *filename) {
FILE *fs = fopen(filename, "r+"); // Открываем файл для чтения
if (!fs)
return -1;
//Read file
rewind(fs); // Перематываем файл назад
char tmp[__MAX_SIZE];
int total = 0;
while (fgets(tmp, __MAX_SIZE, fs)) {
/**
* Тут очень интересная штука
* [^,] - регулярное выражение, которое ищет строку заканчивающуюся на запятую
* А %d - это выражение, которое указывает, что здесь мы ожидаем целове число
**/
sscanf(tmp, "%[^,], %[^,], %[^,], %d , %d", Books[total].ISBN, Books[total].Author, Books[total].Title,
&Books[total].All, &Books[total].Free);
total++;
}
return total;
}
int comparingISBN(char a[14]) //compare which new ISBN existed or not
{
int i;
int temp = -1;
for (i = 0; i < readBook("book.csv"); i++) {
if (strcmp(a, Books[i].ISBN) == 0) // Сравнение строк
temp = i;
}
return temp;
}
//Add
void addingNewBook(const char *filename) {
FILE *fs = fopen(filename, "a+");
book newbook;
printf("ISBN:");
gets(newbook.ISBN);
if (comparingISBN(newbook.ISBN) != -1)
fclose(fs);
else {
printf("\nAuthor's name:");
gets(newbook.Author);
printf("\nBook's title:");
gets(newbook.Title);
printf("\nAll:");
scanf("%d", &newbook.All);
printf("\nFree:");
scanf("%d", &newbook.Free);
fprintf(fs, "%s, %s, %s, %d, %d\n", newbook.ISBN, newbook.Author, newbook.Title, newbook.All,
newbook.Free); // Вывод в файл
fclose(fs);
}
}
//Search
void searchingBook(const char *filename) {
FILE *fs = fopen(filename, "r");
char searchitem[14];
rewind(fs);
printf("ISBN:");
gets(searchitem);
int n = comparingISBN(searchitem);
if (n == -1)
fclose(fs);
else {
printf("%s, %s, %s, %d, %d\n", Books[n].ISBN, Books[n].Author, Books[n].Title, Books[n].All, Books[n].Free);
fclose(fs);
}
}
//Delete
void deletingBook(const char *filename) {
FILE *fs;
char deleteitem[__MAX_SIZE];
printf("ISBN:");
gets(deleteitem);
fs = fopen(filename, "r");
rewind(fs);
int k = comparingISBN(deleteitem);
int n = readBook(filename);
fclose(fs);
if (k != -1) {
fs = fopen(filename, "w");
int i;
for (i = 0; i < n; i++) {
if (i != k)
//printf("%s, %s, %s, %d, %d\n", Books[i].ISBN, Books[i].Author, Books[i].Title, Books[i].All, Books[i].Free);
fprintf(fs, "%s, %s, %s, %d, %d\n", Books[i].ISBN, Books[i].Author, Books[i].Title, Books[i].All,
Books[i].Free);
}
fclose(fs);
} else
printf(" ");
}
//Edit
void swap(int *a, int *b) {
int temp;
temp = *b;
*b = *a;
*a = temp;
}
void strswap(char a[], char b[]) {
char tmp[__MAX_SIZE];
strcpy(tmp, b);
strcpy(b, a);
strcpy(a, tmp);
}
void sortingBook(const char *filename) {
FILE *fs = fopen(filename, "r");
int i, j;
int n = readBook("book.csv");
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (strcmp(Books[i].ISBN, Books[j].ISBN) < 0) {
strswap(Books[i].ISBN, Books[j].ISBN);
strswap(Books[i].Author, Books[j].Author);
strswap(Books[i].Title, Books[j].Title);
swap(&Books[i].All, &Books[j].All);
swap(&Books[i].Free, &Books[j].Free);
}
}
}
for (i = 0; i < n; i++)
printf("%s | %s | %s | %d | %d\n", Books[i].ISBN, Books[i].Author, Books[i].Title, Books[i].All, Books[i].Free);
}
//Student File
int readStudent(const char *filename) {
FILE *fs = fopen(filename, "r+");
if (!fs)
return -1;
//Read file
rewind(fs);
char tmp[__MAX_SIZE];
int total = 0;
while (fgets(tmp, __MAX_SIZE, fs)) {
sscanf(tmp, "%[^,], %[^,], %[^,], %[^,], %[^,], %[^\n]", Students[total].ID, Students[total].FamilyName,
Students[total].Name, Students[total].FatherName, Students[total].Faculty, Students[total].Specialist);
total++;
}
return total;
}
int comparingID(char a[7]) //compare which new ID existed or not
{
int i;
int temp = -1;
for (i = 0; i < readStudent("student.csv"); i++) {
if (strcmp(a, Students[i].ID) == 0)
temp = i;
}
return temp;
}
//Add
void addingNewStudent(const char *filename) {
FILE *fs = fopen(filename, "a+");
student newstudent;
printf("ID:");
gets(newstudent.ID);
if (comparingID(newstudent.ID) != -1)
fclose(fs);
else {
printf("Family Name:");
gets(newstudent.FamilyName);
printf("Name:");
gets(newstudent.Name);
printf("Father Name:");
gets(newstudent.FatherName);
printf("Faculty:");
gets(newstudent.Faculty);
printf("Specialist:");
gets(newstudent.Specialist);
fprintf(fs, "%s, %s, %s, %s, %s, %s\n", newstudent.ID, newstudent.FamilyName, newstudent.Name,
newstudent.FatherName, newstudent.Faculty, newstudent.Specialist);
fclose(fs);
}
}
//Delete
void deletingStudent(const char *filename) {
FILE *fs;
char deleteitem[__MAX_SIZE];
printf("ID:");
gets(deleteitem);
fs = fopen(filename, "r");
rewind(fs);
int k = comparingID(deleteitem);
int n = readStudent(filename);
fclose(fs);
if (k != -1) {
fs = fopen(filename, "w");
int i;
for (i = 0; i < n; i++) {
if (i != k)
fprintf(fs, "%s, %s, %s, %s, %s, %s\n", Students[i].ID, Students[i].FamilyName, Students[i].Name,
Students[i].FatherName, Students[i].Faculty, Students[i].Specialist);
}
fclose(fs);
} else
printf(" ");
}
//Edit
void editingStudent(const char *filename) {
FILE *fs;
student edititem;
printf("ID:");
gets(edititem.ID);
fs = fopen(filename, "r");
rewind(fs);
int k = comparingID(edititem.ID);
int n = readStudent(filename);
fclose(fs);
if (k != -1) {
printf("Family Name:");
gets(edititem.FamilyName);
printf("Name:");
gets(edititem.Name);
printf("Father Name:");
gets(edititem.FatherName);
printf("Faculty:");
gets(edititem.Faculty);
printf("Specialist:");
gets(edititem.Specialist);
fs = fopen(filename, "w");
int i;
for (i = 0; i < n; i++) {
if (i != k)
fprintf(fs, "%s, %s, %s, %s, %s, %s\n", Students[i].ID, Students[i].FamilyName, Students[i].Name,
Students[i].FatherName, Students[i].Faculty, Students[i].Specialist);
}
fprintf(fs, "%s, %s, %s, %s, %s, %s\n", edititem.ID, edititem.FamilyName, edititem.Name, edititem.FatherName,
edititem.Faculty, edititem.Specialist);
fclose(fs);
} else
printf(" ");
}
//Search
void searchingStudent(const char *filename) {
FILE *fs = fopen(filename, "r");
char searchitem[7];
rewind(fs);
printf("ID:");
getchar();
gets(searchitem);
int n = comparingID(searchitem);
if (n == -1)
fclose(fs);
else {
printf("%s, %s, %s, %s, %s, %s\n", Students[n].ID, Students[n].FamilyName, Students[n].Name,
Students[n].FatherName, Students[n].Faculty, Students[n].Specialist);
fclose(fs);
}
}
int readUser(const char *filename) {
FILE *fs = fopen(filename, "r+"); // Открыть файл для чтения
if (!fs)
return -1;
//Read file
rewind(fs); // Перемотка на начало файла
char tmp[__MAX_SIZE];
int total = 0;
while (fgets(tmp, __MAX_SIZE, fs)) {
sscanf(tmp, "%[^,], %[^,], %d , %d", Users[total].Username, Users[total].Password, &Users[total].ADbook,
&Users[total].ADstudent);
total++;
}
return total;
}
//Check
int checkUser(const char *filename) {
FILE *fs = fopen(filename, "r"); // Открываем файл. Строка "r" говорит о том, что мы его открываем на запись.
char login[__MAX_SIZE];
char password[__MAX_SIZE];
printf("Login:");
gets(login); // Читаем строку
printf("Password:");
gets(password); // Читаем пароль
rewind(fs); // Перемотка на начало файла
int n = readUser("user.csv");
int i;
int tp = -1;
for (i = 0; i < n; i++) {
if (strcmp(login, Users[i].Username) == 0 /* сравниваем строки */ && strcmp(password, Users[i].Password) == 0) {
tp = i;
}
}
if (tp >= 0 && tp < n)
return tp;
else
return -1;
// Он забыл закрыть файл!!! Сволочь! Растрелять! Это баг, теперь этот файл будет всегда открыт, пока живет программа
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment