This code implements the registration and logging of two types...

August 27, 2025 at 02:21 PM

#include <stdio.h> #include <string.h> // Tipo di log per distinguere Cliente ordine Ordine typedef enum { StructCliente, StructOrdine } TipoStruct; // Struct Cliente typedef struct { char nome[20]; char cognome[20]; char email[50]; int puntiFedelta; } Cliente; // Struct Ordine typedef struct { char prodotto[30]; char codiceid[20]; int quantita; double prezzo; } Ordine; // Struct Registro con tag e union per dati Cliente ordine Ordine typedef struct { TipoStruct tipo; union { Cliente client; Ordine ordine; } data; } Registro; // Funzione unica per gestire il log void gestisciLog(Registro* registro) { FILE* f; f = fopen("log.txt", "a"); if (!f) { perror("Errore apertura log"); return; } if (registro->tipo == StructCliente) { Cliente* cliente; cliente = &registro->data.client; printf("LOG Cliente: %s %s (%s) - Punti: %d\n", cliente->nome, cliente->cognome, cliente->email, cliente->puntiFedelta); fprintf(f, "LOG Cliente: %s %s (%s) - Punti: %d\n", cliente->nome, cliente->cognome, cliente->email, cliente->puntiFedelta); } else if (registro->tipo == StructOrdine) { Ordine* ordine; ordine = &registro->data.ordine; printf("LOG Ordine: %s C-ID:%s Quantita: %d - Prezzo: %.2f\n", ordine->prodotto, ordine->codiceid, ordine->quantita, ordine->prezzo); fprintf(f, "LOG Ordine: %s C-ID:%s Quantita: %d - Prezzo: %.2f\n", ordine->prodotto, ordine->codiceid, ordine->quantita, ordine->prezzo); } fclose(f); } int main() { char scelta[20]; printf("Vuoi aggiungere: Cliente ordine Ordine? \n"); fgets(scelta, sizeof(scelta), stdin); scelta[strcspn(scelta, "\n")] = 0; Registro registro; if (strcmp(scelta, "Cliente") == 0 || strcmp(scelta, "cliente") == 0) { registro.tipo = StructCliente; printf("Nome: "); fgets(registro.data.client.nome, sizeof(registro.data.client.nome), stdin); registro.data.client.nome[strcspn(registro.data.client.nome, "\n")] = 0; printf("Cognome: "); fgets(registro.data.client.cognome, sizeof(registro.data.client.cognome), stdin); registro.data.client.cognome[strcspn(registro.data.client.cognome, "\n")] = 0; printf("Email: "); fgets(registro.data.client.email, sizeof(registro.data.client.email), stdin); registro.data.client.email[strcspn(registro.data.client.email, "\n")] = 0; printf("Punti Fedelta: "); scanf("%d", &registro.data.client.puntiFedelta); } else if (strcmp(scelta, "Ordine") == 0 || strcmp(scelta, "ordine") == 0) { registro.tipo = StructOrdine; printf("Prodotto: "); fgets(registro.data.ordine.prodotto, sizeof(registro.data.ordine.prodotto), stdin); registro.data.ordine.prodotto[strcspn(registro.data.ordine.prodotto, "\n")] = 0; printf("Codice ID: "); fgets(registro.data.ordine.codiceid, sizeof(registro.data.ordine.codiceid), stdin); registro.data.ordine.codiceid[strcspn(registro.data.ordine.codiceid, "\n")] = 0; printf("Quantita: "); scanf("%d", &registro.data.ordine.quantita); printf("Prezzo: "); scanf("%lf", &registro.data.ordine.prezzo); } else { printf("Scelta non valida.\n"); return 1; } gestisciLog(&registro); return 0; }

This code implements the registration and logging of two types of data: Cliente (Customer) and Ordine (Order), by using struct, union, and enum. Here's a detailed breakdown of its functionality:

Overall Logic

  1. Purpose:
    • The program allows the user to input data for either a Cliente or an Ordine and logs this information to both the console and an external file (log.txt).
  2. Key Concepts:
    • enum TipoStruct: Identifies whether the data being processed is related to a Cliente or an Ordine.
    • union within Registro: Stores either a Cliente or an Ordine as part of a larger structure, depending on the type indicated by the enum.

Step-by-step Functionality

1. Data Structures

  • Cliente Structure: Represents customer data including:

    • nome, cognome, email: Strings representing the customer's first name, last name, and email.
    • puntiFedelta: Integer representing loyalty points.
  • Ordine Structure: Represents order data including:

    • prodotto: Product name.
    • codiceid: Unique identifier for the product.
    • quantita: Quantity of the product ordered.
    • prezzo: Double value representing the price of the order.
  • Registro Structure: Keeps track of:

    • tipo: An enum type field (StructCliente or StructOrdine) indicating the type of data.
    • data (a union): Can hold either a Cliente or Ordine record.

2. User Input

  • The program begins by prompting the user to choose whether they want to log Cliente (customer) or Ordine (order) data using a fgets input.

  • If the user selects Cliente:

    • Prompts for nome, cognome, email, and puntiFedelta to define the Cliente structure inside the Registro.
  • If the user selects Ordine:

    • Prompts for prodotto, codiceid, quantita, and prezzo to define the Ordine structure inside the Registro.
  • If the input is invalid:

    • The program terminates by outputting "Scelta non valida" (Invalid choice).

3. Logging via gestisciLog

  • The function gestisciLog takes a pointer to the Registro structure and determines how to process it based on the tipo field:

    • For StructCliente:
      • Logs details of the Cliente (name, last name, email, and loyalty points) to both the console and log.txt.
    • For StructOrdine:
      • Logs details of the Ordine (product, ID, quantity, and price) to both the console and log.txt.
  • The function uses fprintf to append the details to the file (log.txt), opening it in append mode. If the file cannot be opened, it outputs an error message using perror.

4. Closing and Output

  • The program closes the log.txt file after writing and exits successfully when the logging operation is complete.

Example Interaction

Scenario 1: Logging a Cliente

  • User Input:
    Vuoi aggiungere: Cliente ordine Ordine?
    Cliente
    Nome: Mario
    Cognome: Rossi
    Email: mario.rossi@email.com
    Punti Fedelta: 100
    
  • Console Output:
    LOG Cliente: Mario Rossi (mario.rossi@email.com) - Punti: 100
    
  • Contents of log.txt:
    LOG Cliente: Mario Rossi (mario.rossi@email.com) - Punti: 100
    

Scenario 2: Logging an Ordine

  • User Input:
    Vuoi aggiungere: Cliente ordine Ordine?
    Ordine
    Prodotto: Laptop
    Codice ID: 12345
    Quantita: 2
    Prezzo: 999.99
    
  • Console Output:
    LOG Ordine: Laptop C-ID:12345 Quantita: 2 - Prezzo: 999.99
    
  • Contents of log.txt:
    LOG Ordine: Laptop C-ID:12345 Quantita: 2 - Prezzo: 999.99
    

Key Points

  1. Union and Enum Usage: The union in Registro allows efficient storage of either a Cliente or Ordine without allocating memory for both, with the TipoStruct enum guiding which data to access.
  2. Input Handling: The program sanitizes input by removing newlines using strcspn and ensures valid conversion for numeric fields.
  3. Logging: The design separates the input gathering and logging logic, ensuring modularity via the gestisciLog function.

This approach is efficient for simple applications requiring selective logging of different types of structured data.

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