This code implements a text-based database management system in C...

September 3, 2025 at 11:11 PM

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <regex.h> #define DataBase "TEST/database.txt" // Funzione per validare il input utente int inputValido(const char *chiave) { regex_t regex; int controllo = regcomp(&regex, "^[a-zA-Z0-9]+$", REG_EXTENDED); if (controllo) { fprintf(stderr, "Errore compilazione regex\n"); return 0; } else { controllo = regexec(&regex, chiave, 0, NULL, 0); regfree(&regex); if (!controllo) { return 1; } else { return 0; } } } //Funzione per validare se la chiave non e gia presente int giaPresente(const char *chiave) { FILE *file =fopen(DataBase, "r"); // Controlo riga per riga se lachiave non e gia presente if(file) { char riga[512], temp[255]; while(fgets(riga, sizeof(riga), file)) { sscanf(riga, "%[^:]", temp); if(strcmp(temp, chiave) == 0) { printf("Chiave gia presente.\n"); fclose(file); return 1; } } fclose(file); return 0; } } // Funzione per aggiungere un record alla base di dati void aggiungiRecord() { char chiave[255], valore[255], record[512]; // Prendo in input la chaive e il valore da aggiungere alla base di dati printf("Inserisci chiave: "); fgets(chiave, sizeof(chiave), stdin); chiave[strcspn(chiave, "\n")] = 0; // Controllo se la chaive e valida e non presente gia nel file if(!inputValido(chiave) && !giaPresente(chiave)){ printf("Chiave non valida.\n"); return; } printf("Inserisci valore: "); fgets(valore, sizeof(valore), stdin); valore[strcspn(valore, "\n")] = 0; // COncateno la chiave al valore separandoli con un : snprintf(record, sizeof(record), "%s:%s\n", chiave, valore); // Accedo al file e concateno la nuova riga alla fine del file FILE *file = fopen(DataBase, "a"); if (file) { fputs(record, file); fclose(file); printf("Record aggiunto.\n"); } else { perror("Errore apertura database"); } } // Funzione per settaciare una base di dati per dato una chiave void cercaRecord() { char chiave[64], riga[512]; // Prendo in input la chaive da cercare printf("Chiave da cercare: "); fgets(chiave, sizeof(chiave), stdin); chiave[strcspn(chiave, "\n")] = 0; // Accedo al file data base FILE *file = fopen(DataBase, "r"); if (!file) { perror("Errore apertura database"); return; } // Controllo riga per riga se la chiave e presente all'interno della base di dati int trovato = 0; char temp[255]; while (fgets(riga, sizeof(riga), file)) { sscanf(riga, "%[^:]", temp); if (strcmp(temp, chiave) == 0) { fputs(riga, stdout); trovato = 1; } } if (!trovato) printf("Nessun record trovato.\n"); fclose(file); } // Comparator per qsort int comp(const void *a, const void *b) { const char *pa = *(const char **)a; const char *pb = *(const char **)b; return strcmp(pa, pb); } // Funzione per ordinare la base di dati void ordinaDatabase() { // Accedo alla base di dati in modalita lettura FILE *file = fopen(DataBase, "r"); if (!file) { perror("Errore apertura database"); return; } char *righe[2048]; int count = 0; char buffer[2048]; // Salvo il contenuto del file nel buffer while (fgets(buffer, sizeof(buffer), file) && count < 2048) { // Duplico le righe salvate nel buffe in righe righe[count] = strdup(buffer); if (!righe[count]) { perror("malloc fallita"); fclose(file); return; } count++; } fclose(file); // Funzione per il sorting delle righe qsort(righe, count, sizeof(char *), comp); // Apro il file in modalita scrittura file = fopen(DataBase, "w"); if (!file) { perror("Errore scrittura database"); for (int i = 0; i < count; i++) free(righe[i]); return; } // Riscrivo le righe riordinate nel file for (int i = 0; i < count; i++) { fputs(righe[i], file); free(righe[i]); } fclose(file); printf("Database ordinato.\n"); } // Funzione per la stampa della base di dati void mostraDatabase() { // Accedo al file FILE *file = fopen(DataBase, "r"); if (!file) { perror("Errore apertura database"); return; } // Stampo il contenuto della base di dati riga per riga char riga[512]; printf("Contenuto database:\n"); while (fgets(riga, sizeof(riga), file)) { fputs(riga, stdout); } fclose(file); } int main() { int scelta; // In caso la base di dati non ci sia ancora lo creo FILE *file = fopen(DataBase, "a"); if (file) fclose(file); // Menu persistente per l'interazione utente programma do { printf("\nGestore Database di Testo\n"); printf("1) Aggiungi Record\n"); printf("2) Cerca Record\n"); printf("3) Ordina Base di Dati\n"); printf("4) Mostra Base di Dati\n"); printf("5) Esci\n"); printf("Scelta: "); if (scanf("%d", &scelta) != 1) { while (getchar() != '\n'); continue; } getchar(); // consuma newline switch (scelta) { case 1: aggiungiRecord(); break; case 2: cercaRecord(); break; case 3: ordinaDatabase(); break; case 4: mostraDatabase(); break; case 5: printf("Chiusura.\n"); break; default: printf("Scelta non valida.\n"); } } while (scelta != 5); return 0; }

This code implements a text-based database management system in C that allows a user to perform basic operations on a plaintext "database" stored in a file. Here's a breakdown of what the code does:

Key Functionalities:

  1. Validation of User Input (inputValido):

    • Ensures that the user-provided key is only composed of alphanumeric characters (a-z, A-Z, 0-9).
    • Uses regular expressions to validate the input.
  2. Check if a Key is Already Present (giaPresente):

    • Opens the database file in read mode.
    • Iterates through its lines to check if the provided key (the left-hand side of the key:value pair) is already present.
    • Prints a message if the key is found.
  3. Add a Record to the Database (aggiungiRecord):

    • Prompts the user for a key and a value.
    • Validates the key and checks for duplicates.
    • If the key is valid and not present, appends the key-value pair (in key:value format) to the database file.
  4. Search for a Record by Key (cercaRecord):

    • Accepts a key as input.
    • Searches the database for any records that match the key on the left-hand side of key:value pairs.
    • If found, it prints the entire matching line(s).
  5. Sort the Database (ordinaDatabase):

    • Reads all lines from the database into an array of strings.
    • Sorts the array in ascending lexicographical order using qsort.
    • Writes the sorted content back into the database file.
  6. Display the Entire Database (mostraDatabase):

    • Prints all lines from the database file to the terminal.
  7. Menu and User Interaction (main):

    • Implements a looped menu allowing the user to select:
      1. Add a new record.
      2. Search for a record by key.
      3. Sort the database.
      4. View all records.
      5. Exit the program.
    • If the database file does not exist, it is created.

File Handling:

The database is stored as a text file (TEST/database.txt). Each record is stored in the format:

key:value

Workflow:

  1. The user is presented with a menu to interact with the database.
  2. Based on the user's choice, an appropriate function is executed.
  3. Records are validated (e.g., for valid characters, duplicates) where necessary to ensure data integrity.

Error Handling:

  • Handles errors such as invalid file operations (e.g., failure to open or write to the database file).
  • Ensures proper memory management, like freeing dynamically allocated memory after sorting.
  • Contains simple input validation to handle improper choices in the menu or invalid input for keys/values.

Example Use Case:

  1. Add a record: key1:val1.
  2. Add another record: key2:val2.
  3. Search for key1 — it will display key1:val1.
  4. Sort the database — records will be reordered lexicographically.
  5. Display all records — prints the contents of the database.
  6. Exit.

This program emulates a rudimentary database system using simple file operations and input/output handling in C.

Generate your own explanations
Download our vscode extension
Read other generated explanations

Built by @thebuilderjr
Sponsored by beam analytics
Read our terms and privacy policy
Forked from openai-quickstart-node