This code implements a simple text-based database manager in C....

September 3, 2025 at 11:09 PM

#include <stdio.h> #include <stdlib.h> #include <string.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 fiaPresente(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(riga, 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 simple text-based database manager in C. It allows users to interact with a file-based database containing key-value pairs (in the format key:value). The database is stored in a text file (TEST/database.txt). Here's what the program does:

High-level Summary:

  1. Key Features:

    • Add a key:value pair to the database.
    • Search for a record by key.
    • Sort the database alphabetically by key.
    • Display all database contents.
    • Exit the program.
  2. Menu Interaction: The program operates through a persistent menu that lets the user select the desired operation.

  3. Database File: The database file stores each key:value pair on a new line. If the file doesn't exist, it is automatically created.


Detailed Features and Code Behavior:

1. Validation (inputValido):

The inputValido function uses regular expressions to check if the input key is valid:

  • A valid key can only contain alphanumeric characters ([a-zA-Z0-9]).
  • If the key doesn't match this pattern, the function returns 0.

2. Check for Duplicates (fiaPresente):

The fiaPresente function checks if a given key is already present in the database file:

  • The file is read line by line.
  • Each line is parsed to extract its key.
  • If the key matches the provided one, it indicates the key already exists.

3. Add Records (aggiungiRecord):

  • Prompts the user to input a key and value.
  • Validates the key using inputValido.
  • Checks the database using fiaPresente to ensure the key is not already in use.
  • If the input is valid and unique, it appends the new key:value pair to the database file.

4. Search Records (cercaRecord):

  • Prompts the user for a key and searches for it in the database file.
  • Reads the file line by line, extracting the key from each line.
  • If the specified key is found, the corresponding record is printed; otherwise, it prints "No record found."

5. Sort Database (ordinaDatabase):

  • Reads all the lines (records) from the database file into memory.
  • Sorts the records alphabetically by key using qsort.
  • Writes the sorted records back into the database file, overwriting its contents.

6. Display Database (mostraDatabase):

  • Opens the database file and displays its contents line by line.
  • Ensures that the entire database file is presented in the console.

7. Menu System (main):

  • Implements a persistent menu using a do-while loop.
  • Options:
    1. Add a record.
    2. Search for a record.
    3. Sort the database.
    4. Display the database.
    5. Exit the program.
  • Users enter their choice (validated) and the corresponding function is invoked.

8. Error Handling:

  • Ensures that the database file is properly opened/closed.
  • Handles potential errors such as missing files or failed memory allocation during sorting.

Issues in the Code:

  • Missing headers: The function inputValido uses regex-related functionality, but <regex.h> is not included.
  • Typographical Errors:
    • The function fiaPresente incorrectly declares File instead of FILE for file handling.
    • Missing closing semicolons in a few places (e.g., printf("Chiave gia presente.\n") in fiaPresente).
    • Function giaPresente is called in aggiungiRecord instead of the correct fiaPresente function.
  • Bug in Searching (cercaRecord):
    • It attempts to compare the entire line (riga) with the key (chiave).
    • Should extract the key portion from the file line using sscanf and compare it.
  • Potential Overflow:
    • Fixed-size buffers may lead to overflow if inputs exceed their sizes.

Correct Usage Scenario:

The code is designed to maintain and manipulate a simple file-based key-value store. Here's an example workflow:

  1. Run the program, initializing the file if necessary.
  2. Use the menu to:
    • Add new key:value pairs.
    • Search by specifying a key.
    • Sort and display records.

This provides a functional but basic interface for managing a minimalistic textual database 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