Indice

Esercitazione 1 (ripasso C)

Esercizio 1

Scrivere un programma C che prende in ingresso 2 interi e 2 stringhe. Stampare a video tutta la lista degli argomenti (argv) e tutte le variabili d'ambiente del programma (envp). Ricordare che una possibile segnatura della funzione main e':

int main(int argc, char *argv[], char *envp[]);

Esercizio 2

Scrivere un programma che, dato un array di N elementi interi, costruisca un albero binario di ricerca (cioè per ogni nodo dell'albero, l'elemento del nodo è maggiore di tutti gli elementi del sottoalbero di sinistra e minore o uguale di tutti gli elementi del sottoalbero di destra). Implementare le seguenti funzioni:

struct node_t *buildTree(long elem, struct node_t *t); // costruisce l'albero e restituisce il nodo radice
long getMin(struct node_t *root);       // restituisce il valore minimo
long getMax(struct node_t *root);       // restituisce il valore massimo
void printInOrder(struct node_t *root); // stampa gli elementi in modo ordinato
void deleteTree(struct node_t *root);   // cancella tutti i nodi dell'albero

Definire il tipo 'struct node_t' opportunamente. Implementare tutte le funzioni usando la ricorsione. Il main e' il seguente:

int main(int argc, char *argv[]) {
    struct node_t *root = NULL;
    const long array_size = 10;
    long array[] = { 12, 32, 18, -1, 0, 18, -5, 54, 28, 15};
 
    for(long i=0; i<array_size; ++i)
	root = buildTree(array[i], root);
 
    printf("Min: %ld\n", getMin(root));
    printf("Max: %ld\n", getMax(root));
 
    printInOrder(root);
    printf("\n");
 
    deleteTree(root);
    return 0;
}

Esercizio 3

Scrivere una funzione 'mystrcat' con la seguente segnatura:

const char *mystrcat(char* buffer, int buffer_size, char *prima, ...);

La funzione prende un buffer, la lunghezza del buffer ed almeno uno stringa. Le stringhe possono essere un numero variabile (>1). La funzione concatena tutte le stringhe nel 'buffer' e ritorna il buffer stesso. ATTENZIONE alla gestione della memoria!

Utilizzare il seguente main:

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define RIALLOCA(buf, newsize) \
    <inserire il codice per riallocare buf> 
 
char* mystrcat(char *buf, size_t sz, char *first, ...) {
  <implementare il codice>
}  
 
int main() {
  char *buffer=NULL;
  RIALLOCA(buffer, 16);  // macro che effettua l'allocazione
  buffer[0]='\0';
  buffer = mystrcat(buffer, 16, "prima stringa", "seconda", "terza molto molto molto lunga", "quarta", "quinta lunga", "ultima!",NULL);
  printf("%s\n", buffer);     
  free(buffer);
  return 0;
}

NOTA: Che cosa puo' succedere al programma se invece di

 printf("%s\n", buffer);

si fosse scritto:

 
 printf("%s\n", mystrcat(buffer, 16, "prima stringa", "seconda", "terza molto molto molto lunga", "quarta", "quinta lunga", "ultima!",NULL));

Esercizio 4

Non utilizzando la funzioni di libreria 'getopt' (man 3 getopt), scrivere un programma che effettua il parsing della linea di comando e che riconosce le seguenti opzioni:

-n <numero> -s <stringa> -m <altro-numero> -h. 

Il programma dovrà stampare le opzioni riconosciute con il relativo argomento. L'opzione -h non ha argomento e corrisponde al messaggio di help (program usage). Se e' presente l'opzione -h dovra' essere stampato solo il messaggio di usage cioè:

nome-programma -n <numero> -s <stringa> -m <numero> -h

Se ci sono opzioni non riconosciute queste dovranno essere stampate a video con il messaggio “opzione X non riconosciuta”. Per convertire le stringhe in interi usare la funzione di libreria atoi (vedere man 3 atoi) o meglio ancora la funzione strtol (vedere man strtol). Testare il programma con i seguenti casi (supponiamo che l'eseguibile si chiami cmdlineparsing):

cmdlineparsing -n 10 -m 11 -s 'ciao mondo' 
cmdlineparsing -n 10 -h     // deve stampare il messaggio di usage 
cmdlineparsing -n 10 -k 12  // k e' una opzione non riconosciuta
cmdlineparsing ----n 10 -s-s 'ciao mondo'  // deve stampare -n: 10 e -s: -s
cmdlineparsing -n10 -m11 -s'ciao mondo'  // deve stampare gli argomenti come nel primo caso
cmdlineparsing -n -m 11   // deve stampare un messaggio di errore per -n