fork download
  1. /*
  2.   scifi_terminal.c
  3.   Simple inventory & text storage terminal in C.
  4.   - Command-driven (type commands like "inventory", "add", "save file.txt", "load file.txt")
  5.   - File-based storage (plain text CSV)
  6.   - Minimal dependencies; intended for old Windows machines
  7.   - 80s sci-fi terminal style (ASCII)
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #define INITIAL_CAP 64
  16. #define LINE_BUF 512
  17. #define NAME_LEN 128
  18.  
  19. typedef struct {
  20. char name[NAME_LEN];
  21. long qty;
  22. char note[LINE_BUF];
  23. } Item;
  24.  
  25. typedef struct {
  26. Item *items;
  27. size_t len;
  28. size_t cap;
  29. } Inventory;
  30.  
  31. void init_inventory(Inventory *inv){
  32. inv->len = 0;
  33. inv->cap = INITIAL_CAP;
  34. inv->items = (Item*)malloc(sizeof(Item) * inv->cap);
  35. if(!inv->items){ fprintf(stderr,"Memory allocation failed\n"); exit(1); }
  36. }
  37.  
  38. void free_inventory(Inventory *inv){
  39. if(inv->items) free(inv->items);
  40. inv->items = NULL;
  41. inv->len = inv->cap = 0;
  42. }
  43.  
  44. void grow_if_needed(Inventory *inv){
  45. if(inv->len >= inv->cap){
  46. inv->cap *= 2;
  47. Item *n = (Item*)realloc(inv->items, sizeof(Item) * inv->cap);
  48. if(!n){ fprintf(stderr,"Reallocation failed\n"); exit(1); }
  49. inv->items = n;
  50. }
  51. }
  52.  
  53. void add_item(Inventory *inv, const char *name, long qty, const char *note){
  54. grow_if_needed(inv);
  55. strncpy(inv->items[inv->len].name, name, NAME_LEN-1);
  56. inv->items[inv->len].name[NAME_LEN-1] = '\0';
  57. inv->items[inv->len].qty = qty;
  58. if(note){
  59. strncpy(inv->items[inv->len].note, note, LINE_BUF-1);
  60. inv->items[inv->len].note[LINE_BUF-1] = '\0';
  61. } else {
  62. inv->items[inv->len].note[0] = '\0';
  63. }
  64. inv->len++;
  65. }
  66.  
  67. int find_item_index(Inventory *inv, const char *name){
  68. for(size_t i=0;i<inv->len;i++){
  69. if(strcmp(inv->items[i].name, name) == 0) return (int)i;
  70. }
  71. return -1;
  72. }
  73.  
  74. void remove_item(Inventory *inv, const char *name){
  75. int idx = find_item_index(inv, name);
  76. if(idx < 0){ printf("No item named '%s' found.\n", name); return; }
  77. for(size_t i = idx; i+1 < inv->len; ++i) inv->items[i] = inv->items[i+1];
  78. inv->len--;
  79. printf("Removed '%s'.\n", name);
  80. }
  81.  
  82. void list_inventory(Inventory *inv){
  83. puts("┌────────────────────────────────────────────────────────────┐");
  84. puts("│ S Y S T E M I N V E N T O R Y │");
  85. puts("└────────────────────────────────────────────────────────────┘");
  86. if(inv->len == 0){
  87. puts("[empty]");
  88. return;
  89. }
  90. printf("%-3s %-30s %-8s %s\n", "No", "Name", "Quantity", "Note");
  91. puts("------------------------------------------------------------------");
  92. for(size_t i=0;i<inv->len;i++){
  93. printf("%-3zu %-30s %-8ld %s\n", i+1, inv->items[i].name, inv->items[i].qty, inv->items[i].note);
  94. }
  95. }
  96.  
  97. int save_inventory(Inventory *inv, const char *filename){
  98. FILE *f = fopen(filename, "w");
  99. if(!f) return 0;
  100. // simple CSV: name,qty,note
  101. for(size_t i=0;i<inv->len;i++){
  102. // escape commas by replacing with semicolon to keep simple
  103. char name_safe[NAME_LEN]; char note_safe[LINE_BUF];
  104. strncpy(name_safe, inv->items[i].name, NAME_LEN); name_safe[NAME_LEN-1]='\0';
  105. strncpy(note_safe, inv->items[i].note, LINE_BUF); note_safe[LINE_BUF-1]='\0';
  106. for(char *p=name_safe; *p; ++p) if(*p==',') *p=';';
  107. for(char *p=note_safe; *p; ++p) if(*p==',') *p=';';
  108. fprintf(f, "%s,%ld,%s\n", name_safe, inv->items[i].qty, note_safe);
  109. }
  110. fclose(f);
  111. return 1;
  112. }
  113.  
  114. int load_inventory(Inventory *inv, const char *filename){
  115. FILE *f = fopen(filename, "r");
  116. if(!f) return 0;
  117. char line[LINE_BUF];
  118. inv->len = 0; // clear current (keeps cap)
  119. while(fgets(line, sizeof(line), f)){
  120. // remove newline
  121. char *nl = strchr(line, '\n'); if(nl) *nl = '\0';
  122. // split by first two commas
  123. char *a = strtok(line, ",");
  124. char *b = strtok(NULL, ",");
  125. char *c = strtok(NULL, ""); // remainder
  126. if(!a || !b) continue;
  127. long qty = atol(b);
  128. add_item(inv, a, qty, c?c:"");
  129. }
  130. fclose(f);
  131. return 1;
  132. }
  133.  
  134. void clear_inventory(Inventory *inv){
  135. inv->len = 0;
  136. puts("Inventory cleared.");
  137. }
  138.  
  139. void print_banner(){
  140. puts("############################################################");
  141. puts("# ███████╗ ██████╗ ██╗ ██████╗ ██╗ ██╗ 80s SCI-FI TERMINAL #");
  142. puts("# ██╔════╝██╔════╝ ██║██╔═══██╗██║ ██║ #");
  143. puts("# ███████╗██║ ███╗██║██║ ██║██║ ██║ #");
  144. puts("# ╚════██║██║ ██║██║██║ ██║██║ ██║ #");
  145. puts("# ███████║╚██████╔╝██║╚██████╔╝╚██████╔╝ #");
  146. puts("############################################################");
  147. puts("Type 'help' for commands. (e.g. add, inventory, save file.txt, load file.txt, exit)");
  148. }
  149.  
  150. void to_lower_str(char *s){
  151. for(char *p=s; *p; ++p) *p = (char)tolower((unsigned char)*p);
  152. }
  153.  
  154. void help_text(){
  155. puts("Commands:");
  156. puts(" help - show this help");
  157. puts(" inventory - list inventory");
  158. puts(" add NAME QTY [NOTE] - add an item, e.g. add bolts 20 \"for racks\"");
  159. puts(" remove NAME - remove by exact name");
  160. puts(" save FILENAME - save inventory to a file (CSV)");
  161. puts(" load FILENAME - load inventory from a file (replaces current)");
  162. puts(" clear - clear inventory in memory");
  163. puts(" echo TEXT - append TEXT to a journal.txt file (light text storage)");
  164. puts(" view FILE - print a plain text file to screen");
  165. puts(" exit - exit program");
  166. }
  167.  
  168. void append_to_file(const char *filename, const char *text){
  169. FILE *f = fopen(filename, "a");
  170. if(!f){ printf("Couldn't open %s for append.\n", filename); return; }
  171. fprintf(f, "%s\n", text);
  172. fclose(f);
  173. }
  174.  
  175. void view_file(const char *filename){
  176. FILE *f = fopen(filename, "r");
  177. if(!f){ printf("Couldn't open %s\n", filename); return; }
  178. char line[LINE_BUF];
  179. while(fgets(line, sizeof(line), f)) fputs(line, stdout);
  180. fclose(f);
  181. }
  182.  
  183. int main(void){
  184. Inventory inv;
  185. init_inventory(&inv);
  186. print_banner();
  187.  
  188. char raw[LINE_BUF];
  189. while(1){
  190. printf("\n> ");
  191. if(!fgets(raw, sizeof(raw), stdin)) break;
  192. // trim newline
  193. char *nl = strchr(raw, '\n'); if(nl) *nl = '\0';
  194. // skip empty
  195. char tmp[LINE_BUF];
  196. strncpy(tmp, raw, LINE_BUF-1); tmp[LINE_BUF-1]='\0';
  197. // parse first token as command
  198. char *saveptr = NULL;
  199. char *tok = strtok_r(tmp, " ", &saveptr);
  200. if(!tok) continue;
  201. char cmd[64]; strncpy(cmd, tok, sizeof(cmd)-1); cmd[sizeof(cmd)-1] = '\0';
  202. to_lower_str(cmd);
  203.  
  204. if(strcmp(cmd, "help") == 0){
  205. help_text();
  206. } else if(strcmp(cmd, "inventory") == 0 || strcmp(cmd, "list") == 0){
  207. list_inventory(&inv);
  208. } else if(strcmp(cmd, "add") == 0){
  209. // we need real arguments from raw (not lowered tmp), so parse from raw
  210. // format: add NAME QTY [NOTE...]
  211. char *p = raw + strlen("add");
  212. while(*p && isspace((unsigned char)*p)) p++;
  213. if(!*p){ printf("Usage: add NAME QTY [NOTE]\n"); continue; }
  214. // get name
  215. char name[NAME_LEN]; long qty = 0; char note[LINE_BUF] = "";
  216. // get first token = name
  217. char *s = p;
  218. char *space = strchr(s, ' ');
  219. if(!space){ printf("Usage: add NAME QTY [NOTE]\n"); continue; }
  220. size_t namelen = (size_t)(space - s);
  221. if(namelen >= NAME_LEN) namelen = NAME_LEN-1;
  222. strncpy(name, s, namelen); name[namelen] = '\0';
  223. // skip spaces
  224. s = space;
  225. while(*s && isspace((unsigned char)*s)) s++;
  226. if(!*s){ printf("Usage: add NAME QTY [NOTE]\n"); continue; }
  227. // read qty
  228. char qtystr[64];
  229. int i=0;
  230. while(*s && !isspace((unsigned char)*s) && i < 63) qtystr[i++] = *s++;
  231. qtystr[i] = '\0';
  232. qty = atol(qtystr);
  233. while(*s && isspace((unsigned char)*s)) s++;
  234. if(*s){
  235. // remaining is note
  236. strncpy(note, s, LINE_BUF-1); note[LINE_BUF-1]='\0';
  237. }
  238. // if item exists, increase qty and optionally update note
  239. int idx = find_item_index(&inv, name);
  240. if(idx >= 0){
  241. inv.items[idx].qty += qty;
  242. if(note[0]) strncpy(inv.items[idx].note, note, LINE_BUF-1);
  243. printf("Updated '%s' -> qty=%ld\n", name, inv.items[idx].qty);
  244. } else {
  245. add_item(&inv, name, qty, note);
  246. printf("Added '%s' qty=%ld\n", name, qty);
  247. }
  248. } else if(strcmp(cmd, "remove") == 0){
  249. char *p = raw + strlen("remove");
  250. while(*p && isspace((unsigned char)*p)) p++;
  251. if(!*p){ printf("Usage: remove NAME\n"); continue; }
  252. remove_item(&inv, p);
  253. } else if(strcmp(cmd, "save") == 0){
  254. char *p = raw + strlen("save");
  255. while(*p && isspace((unsigned char)*p)) p++;
  256. if(!*p){ printf("Usage: save filename\n"); continue; }
  257. if(save_inventory(&inv, p)) printf("Saved to %s\n", p);
  258. else printf("Failed to save to %s\n", p);
  259. } else if(strcmp(cmd, "load") == 0){
  260. char *p = raw + strlen("load");
  261. while(*p && isspace((unsigned char)*p)) p++;
  262. if(!*p){ printf("Usage: load filename\n"); continue; }
  263. if(load_inventory(&inv, p)) printf("Loaded %s\n", p);
  264. else printf("Failed to load %s\n", p);
  265. } else if(strcmp(cmd, "clear") == 0){
  266. clear_inventory(&inv);
  267. } else if(strcmp(cmd, "echo") == 0){
  268. char *p = raw + strlen("echo");
  269. while(*p && isspace((unsigned char)*p)) p++;
  270. if(!*p){ printf("Usage: echo TEXT\n"); continue; }
  271. append_to_file("journal.txt", p);
  272. printf("Appended to journal.txt\n");
  273. } else if(strcmp(cmd, "view") == 0){
  274. char *p = raw + strlen("view");
  275. while(*p && isspace((unsigned char)*p)) p++;
  276. if(!*p){ printf("Usage: view filename\n"); continue; }
  277. view_file(p);
  278. } else if(strcmp(cmd, "exit") == 0 || strcmp(cmd, "quit") == 0){
  279. puts("Shutting down...");
  280. break;
  281. } else {
  282. printf("Unknown command: '%s' (type help)\n", cmd);
  283. }
  284. }
  285.  
  286. free_inventory(&inv);
  287. return 0;
  288. }
  289.  
Success #stdin #stdout 0.01s 5320KB
stdin
/*  Berechnung des Hamming-Abstandes zwischen zwei 128-Bit Werten in 	*/
/*	einer Textdatei. 													*/
/*  Die Werte müssen auf einer separaten Zeile gespeichert sein			*/
/* 																		*/
/*	Erstellt: 17.5.2010													*/
/*  Autor: Thomas Scheffler												*/

#include <stdio.h>
#include <stdlib.h>

#define ARRAY_SIZE 32

unsigned Hamdist(unsigned x, unsigned y)
{
  unsigned dist = 0, val = x ^ y;
 
  // Count the number of set bits
  while(val)
  {
    ++dist; 
    val &= val - 1;
  }
 
  return dist;
}



int main (void)
{
	char hex;
	int i;
	int a[ARRAY_SIZE];
	int b[ARRAY_SIZE];
	int hamDist = 0;
	FILE* fp;
	
	//Arrays mit 0 initialisieren
	for (i = 0; i < ARRAY_SIZE; ++i)
	{
  		a[i] = 0;
  		b[i] = 0;
	}

	
	fp = fopen("hex.txt","r");
	if (fp == NULL) 
	{
		printf("Die Datei hex.txt wurde nicht gefunden!");
		exit(EXIT_FAILURE);
	}

	i=0;
	printf("1.Zeile einlesen.\n");

 	while((hex=fgetc(fp))!='\n' && hex != EOF)
    {
        a[i]=strtol(&hex,0,16);
		i++;
    }
	i=0;
	printf("2.Zeile einlesen.\n");

 	while((hex=fgetc(fp))!='\n' && hex != EOF)
    {
    	b[i]=strtol(&hex,0,16);
        i++;
    }
	fclose(fp);

	printf("Hamming-Abweichung pro Nibble:\n");
	for (i = 0; i < ARRAY_SIZE; ++i)
	{
		printf ("%i\t%i\t%i\n",a[i],b[i],Hamdist(a[i],b[i]));
		hamDist += Hamdist(a[i],b[i]);
	}
	printf ("\nHamming-Abweichung der Hash-Werte:%d\n",hamDist);
}

stdout
############################################################
#  ███████╗ ██████╗ ██╗ ██████╗ ██╗   ██╗  80s SCI-FI TERMINAL #
#  ██╔════╝██╔════╝ ██║██╔═══██╗██║   ██║                      #
#  ███████╗██║  ███╗██║██║   ██║██║   ██║                      #
#  ╚════██║██║   ██║██║██║   ██║██║   ██║                      #
#  ███████║╚██████╔╝██║╚██████╔╝╚██████╔╝                      #
############################################################
Type 'help' for commands. (e.g. add, inventory, save file.txt, load file.txt, exit)

> Unknown command: '/*' (type help)

> Unknown command: '/*	einer' (type help)

> Unknown command: '/*' (type help)

> Unknown command: '/*' (type help)

> Unknown command: '/*	erstellt:' (type help)

> Unknown command: '/*' (type help)

> 
> Unknown command: '#include' (type help)

> Unknown command: '#include' (type help)

> 
> Unknown command: '#define' (type help)

> 
> Unknown command: 'unsigned' (type help)

> Unknown command: '{' (type help)

> Unknown command: 'unsigned' (type help)

> 
> Unknown command: '//' (type help)

> Unknown command: 'while(val)' (type help)

> Unknown command: '{' (type help)

> Unknown command: '++dist;' (type help)

> Unknown command: 'val' (type help)

> Unknown command: '}' (type help)

> 
> Unknown command: 'return' (type help)

> Unknown command: '}' (type help)

> 
> 
> 
> Unknown command: 'int' (type help)

> Unknown command: '{' (type help)

> Unknown command: '	char' (type help)

> Unknown command: '	int' (type help)

> Unknown command: '	int' (type help)

> Unknown command: '	int' (type help)

> Unknown command: '	int' (type help)

> Unknown command: '	file*' (type help)

> Unknown command: '	' (type help)

> Unknown command: '	//arrays' (type help)

> Unknown command: '	for' (type help)

> Unknown command: '	{' (type help)

> Unknown command: '		a[i]' (type help)

> Unknown command: '		b[i]' (type help)

> Unknown command: '	}' (type help)

> 
> Unknown command: '	' (type help)

> Unknown command: '	fp' (type help)

> Unknown command: '	if' (type help)

> Unknown command: '	{' (type help)

> Unknown command: '		printf("die' (type help)

> Unknown command: '		exit(exit_failure);' (type help)

> Unknown command: '	}' (type help)

> 
> Unknown command: '	i=0;' (type help)

> Unknown command: '	printf("1.zeile' (type help)

> 
> Unknown command: '	while((hex=fgetc(fp))!='\n'' (type help)

> Unknown command: '{' (type help)

> Unknown command: 'a[i]=strtol(&hex,0,16);' (type help)

> Unknown command: '		i++;' (type help)

> Unknown command: '}' (type help)

> Unknown command: '	i=0;' (type help)

> Unknown command: '	printf("2.zeile' (type help)

> 
> Unknown command: '	while((hex=fgetc(fp))!='\n'' (type help)

> Unknown command: '{' (type help)

> Unknown command: '	b[i]=strtol(&hex,0,16);' (type help)

> Unknown command: 'i++;' (type help)

> Unknown command: '}' (type help)

> Unknown command: '	fclose(fp);' (type help)

> 
> Unknown command: '	printf("hamming-abweichung' (type help)

> Unknown command: '	for' (type help)

> Unknown command: '	{' (type help)

> Unknown command: '		printf' (type help)

> Unknown command: '		hamdist' (type help)

> Unknown command: '	}' (type help)

> Unknown command: '	printf' (type help)

> Unknown command: '}' (type help)

> 
>