summary refs log tree commit diff stats
path: root/specials
diff options
context:
space:
mode:
Diffstat (limited to 'specials')
-rw-r--r--specials/bank.c124
-rw-r--r--specials/file-replace.c119
-rw-r--r--specials/file-search.c71
-rw-r--r--specials/string-search.c71
4 files changed, 385 insertions, 0 deletions
diff --git a/specials/bank.c b/specials/bank.c
new file mode 100644
index 0000000..fd45d20
--- /dev/null
+++ b/specials/bank.c
@@ -0,0 +1,124 @@
+/*
+	
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+
+struct account {
+	int number;
+	double amount;
+};
+
+struct bank_state {
+	int accounts;
+	double total_amount;
+};
+
+void show_main_menu(void)
+{
+	printf(
+	"Menu:\n"
+	"	1  Create Account\n"
+	"	2  Check account balance\n"
+	"	3  Withdraw from account\n"
+	"	4  Add to account\n"
+	"	5  Send money\n"
+	"	6  Close account\n"
+	"	7  Check bank status\n"
+	"	8  Exit\n\n"
+	);
+}
+
+int are_you_sure(char *prompt)
+{
+	char c;
+	printf("%s\n", prompt);
+	for (;;) {
+		printf("Are you sure? (y/n): ");
+		scanf("%c", &c);
+		switch (c) {
+		case 'y': case 'Y':
+			return 1;
+		case 'n': case 'N':
+			return 0;
+		}
+		printf("Enter 'y' or 'n' to confirm your choice\n");
+	}
+}
+
+int menu_prompt(int *choice)
+{
+	printf("Choose an option from menu: ");
+	return scanf("%d", choice);
+}
+
+void discard_input_line(void)
+{
+	int c;
+	do {
+		c = getchar();
+	} while (c != '\n' && c != EOF);
+}
+
+FILE *open_database(int *is_created)
+{
+	FILE *f;
+	if (access("bank.db", F_OK) != 0) {
+		// the file does not exist
+		f = fopen("bank.db", "w+b");
+		*is_created = 1;
+	} else if (access("bank.db", R_OK | W_OK) != 0) {
+		printf("Fatal error: Can not open file for reading and writing: Permission Denied\n");
+		exit(65);
+	} else {
+		f = fopen("bank.db", "r+b");
+		if (f == NULL) {
+			printf("Fatal Error: Can not open bank database.\n");
+			exit(64);
+		}
+	}
+	return f;
+}
+
+void read_database(FILE *f, void **data, size_t *size)
+{
+	fseek(f, 0L, SEEK_END);
+	*size = ftell(f);
+	*data = malloc(*size);
+	fread(*data, 1, *size, f);
+}
+
+void make_empty_database(FILE *f)
+{
+	struct bank_state st = { 0, 0.0 };
+	fwrite(&st, 1, sizeof(st), f);
+}
+
+int main(void)
+{
+	int choice, is_created = 0;
+	FILE *f;
+	void *data;
+	size_t size;
+	f = open_database(&is_created);
+	if (is_created) make_empty_database(f);
+	read_database(f, &data, &size);
+	printf(
+	"Bank System\n"
+	"===========\n\n"
+	);
+	for (;;) {
+		show_main_menu();
+		if (menu_prompt(&choice)) break;
+		printf("Invalid choice. Please enter a number to choose an option from the menu.\n");
+		discard_input_line();
+	}
+	printf("%d\n", choice);
+	free(data);
+	fclose(f);
+	return 0;
+}
+
diff --git a/specials/file-replace.c b/specials/file-replace.c
new file mode 100644
index 0000000..2e01367
--- /dev/null
+++ b/specials/file-replace.c
@@ -0,0 +1,119 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+/* for ftruncate */
+#include <unistd.h>
+#include <sys/types.h>
+
+size_t str_length(char *s)
+{
+	size_t n = 0;
+	while (*s++ != '\0') {
+		n++;
+	}
+	return n;
+}
+
+int str_equal(char *a, char *b)
+{
+	do {
+		if (*a++ != *b++) {
+			return 0;
+		}
+	} while (*b != '\0');
+	return 1;
+}
+
+long find_in_file(FILE *f, char *needle)
+{
+	size_t nlen = str_length(needle);
+	long pos = 0;
+	char *str = malloc(nlen + 1);
+	while (!feof(f) || !ferror(f)) {
+		if (fread(str, 1, nlen, f) != nlen) {
+			break;
+		}
+		str[nlen] = '\0';
+		//printf("%ld: %s\n", ftell(f), str);
+		if (str_equal(str, needle)) {
+			return pos;
+		}
+		fseek(f, ++pos, SEEK_SET);
+	}
+	free(str);
+	return -1;
+}
+
+void move_char(FILE *f, long src, long dst)
+{
+	int c;
+	fseek(f, src, SEEK_SET);
+	c = fgetc(f);
+	fseek(f, dst, SEEK_SET);
+	fputc(c, f);
+}
+
+void file_move_contents(FILE *f, long from, long to, long end)
+{
+	int c;
+	long p, q;
+	if (from < to) {
+		// in case of moving to the right side, 
+		// we start from right end and move backwards to the start
+		for (p = end, q = end + to - from; p >= from; p--, q--) {
+			move_char(f, p, q);
+		}
+	} else {
+		// otherwise, we start from the left and move towards
+		// the right
+		for (p = from, q = to; p <= end; p++, q++) {
+			move_char(f, p, q);
+		}
+	}
+}
+
+int main(int argc, char **argv)
+{
+	FILE *f;
+	int fd;
+	long pos;
+	long olen, nlen, end;
+	if (argc < 4) {
+		printf("Usage: %s [file] [needle] [replacement]\n", argv[0]);
+		printf("Replaces needle in the contents of file with replacement.\n\n");
+		return 2;
+	}
+	if (argv[2][0] == '\0') {
+		printf("%s: Invalid needle: needle can not be empty.\n", argv[0]);
+		return 3;
+	}
+	f = fopen(argv[1], "r+");
+	if (f == NULL) {
+		printf("%s: Error: Can not open file `%s` for reading.\n",
+			argv[0], argv[1]);
+		return 1;
+	}
+	pos = find_in_file(f, argv[2]);
+	if (pos == -1) {
+		printf("The string \"%s\" is not found in file `%s`\n",
+			argv[2], argv[1]);
+	} else {
+		printf("The string \"%s\" is found in file `%s` at position %ld\n", argv[2], argv[1], pos);
+		fseek(f, 0L, SEEK_END);
+		end = ftell(f);
+		olen = str_length(argv[2]);
+		nlen = str_length(argv[3]);
+		file_move_contents(f, pos + olen, pos + nlen, end - 1);
+		// write down the replacement in the right place
+		fseek(f, pos, SEEK_SET);
+		fwrite(argv[3], 1, nlen, f);
+		fseek(f, 0L, SEEK_END);
+		end = ftell(f);
+		// truncate the file to the right size
+		fd = fileno(f);
+		ftruncate(fd, end + nlen - olen);
+	}
+	fclose(f);
+	return 0;
+}
+
diff --git a/specials/file-search.c b/specials/file-search.c
new file mode 100644
index 0000000..0644db7
--- /dev/null
+++ b/specials/file-search.c
@@ -0,0 +1,71 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+size_t str_length(char *s)
+{
+	size_t n = 0;
+	while (*s++ != '\0') {
+		n++;
+	}
+	return n;
+}
+
+int str_equal(char *a, char *b)
+{
+	do {
+		if (*a++ != *b++) {
+			return 0;
+		}
+	} while (*b != '\0');
+	return 1;
+}
+
+long find_in_file(FILE *f, char *needle)
+{
+	size_t nlen = str_length(needle);
+	long pos = 0;
+	char *str = malloc(nlen + 1);
+	while (!feof(f) || !ferror(f)) {
+		if (fread(str, 1, nlen, f) != nlen) {
+			break;
+		}
+		str[nlen] = '\0';
+		//printf("%ld: %s\n", ftell(f), str);
+		if (str_equal(str, needle)) {
+			return pos;
+		}
+		fseek(f, ++pos, SEEK_SET);
+	}
+	return -1;
+}
+
+int main(int argc, char **argv)
+{
+	FILE *f;
+	long pos;
+	if (argc < 3) {
+		printf("Usage: %s [file] [needle]\n", argv[0]);
+		printf("Searches for needle in the contents of file.\n\n");
+		return 2;
+	}
+	if (argv[2][0] == '\0') {
+		printf("%s: Invalid needle: needle can not be empty.\n", argv[0]);
+		return 3;
+	}
+	f = fopen(argv[1], "r");
+	if (f == NULL) {
+		printf("%s: Error: Can not open file `%s` for reading.\n",
+			argv[0], argv[1]);
+		return 1;
+	}
+	pos = find_in_file(f, argv[2]);
+	if (pos == -1) {
+		printf("The string \"%s\" is not found in file `%s`\n",
+			argv[2], argv[1]);
+	} else {
+		printf("The string \"%s\" is found in file `%s` at position %ld\n", argv[2], argv[1], pos);
+	}
+	fclose(f);
+	return 0;
+}
+
diff --git a/specials/string-search.c b/specials/string-search.c
new file mode 100644
index 0000000..7fa0ec1
--- /dev/null
+++ b/specials/string-search.c
@@ -0,0 +1,71 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+size_t str_length(char *s)
+{
+	size_t n = 0;
+	while (*s++ != '\0') {
+		n++;
+	}
+	return n;
+}
+
+int str_equal(char *a, char *b)
+{
+	do {
+		if (*a++ != *b++) {
+			return 0;
+		}
+	} while (*b != '\0');
+	return 1;
+}
+
+long find_in_file(FILE *f, char *needle)
+{
+	size_t nlen = str_length(needle);
+	long pos = 0;
+	char *str = malloc(nlen + 1);
+	while (!feof(f) || !ferror(f)) {
+		if (fread(str, 1, nlen, f) != nlen) {
+			break;
+		}
+		str[nlen] = '\0';
+		printf("%ld: %s\n", ftell(f), str);
+		if (str_equal(str, needle)) {
+			return ftell(f);
+		}
+		fseek(f, ++pos, SEEK_SET);
+	}
+	return -1;
+}
+
+int main(int argc, char **argv)
+{
+	FILE *f;
+	long pos;
+	if (argc < 3) {
+		printf("Usage: %s [file] [needle]\n", argv[0]);
+		printf("Searches for needle in the contents of file.\n\n");
+		return 2;
+	}
+	if (argv[2][0] == '\0') {
+		printf("%s: Invalid needle: needle can not be empty.\n", argv[0]);
+		return 3;
+	}
+	f = fopen(argv[1], "r");
+	if (f == NULL) {
+		printf("%s: Error: Can not open file `%s` for reading.\n",
+			argv[0], argv[1]);
+		return 1;
+	}
+	pos = find_in_file(f, argv[2]);
+	if (pos == -1) {
+		printf("The string \"%s\" is not found in file `%s`\n",
+			argv[2], argv[1]);
+	} else {
+		printf("The string \"%s\" is found in file `%s` at position %ld\n", argv[2], argv[1], pos);
+	}
+	fclose(f);
+	return 0;
+}
+