C, 4c, proposta di correzione compito n.3 del 22/02/2017.
-
Testo del compito proposto
-
1) Definizione della struct.
typedef struct lista
{
int data;
char descrizione[30];
char targa[10];
float peso;
char carburante[20];
struct lista* next;
} t_lista;
-
2) Funzione che importa da file di testo in formato csv i dati e li inserisce in una lista dinamica.
t_lista* importa(char* nomefile) {
t_lista* lista = NULL;
FILE* fcsv;
fcsv= fopen(nomefile,"r");
if(fcsv != NULL)
{
// elemento precedente nello scorrimento della lista
t_lista* prec = NULL;
int i=0;
int data;
float peso;
char des[30];
char tar[10];
char car[20];
char *titolo;
// lettura prima riga con nomi dei campi
fscanf(fcsv,"%[^;];%[^;];%[^;];%[^;];%[^;];",
titolo, titolo, titolo, titolo, titolo);
// oppure
// fscanf(fcsv,"%s", titolo);
while(fscanf(fcsv,"%d;%[^;];%[^;];%f;%[^;];",
&data, des, tar, &peso, car) != EOF)
{
if(strcmp(car, "benzina") == 0) {
t_lista* ptr= (t_lista*) malloc(sizeof(t_lista));
ptr->data = data;
ptr->peso = peso;
strcpy(ptr->descrizione ,des);
strcpy(ptr->targa ,tar);
strcpy(ptr->carburante ,car);
ptr->next = NULL;
if(i == 0) {
// caso particolare per il primo elemento letto che è
// anche il primo elemento della lista
lista = ptr;
prec = lista;
}
else {
// il nuovo elemento letto è inserito in append (in coda)
prec->next = ptr;
prec = ptr;
}
i++;
}
}
}
fclose(fcsv);
return lista;
}
-
3) Funzione per la cancellazione di un elemento dalla lista dinamica, eliminazione per targa.
Ritorna 1 se è stato eliminato, 0 altrimenti.
int cancellazione(t_lista* lista, char* targa) {
t_lista* prec = NULL;
t_lista* prossimo = lista;
int b = 0;
if(lista != NULL) {
while((prossimo != NULL) && (b == 0)) {
if (strcmp(prossimo->targa, targa) == 0) {
b = 1;
}
else {
prec = prossimo;
prossimo = prossimo->next;
}
}
if(b == 1) {
if (prec != NULL) prec->next = prossimo->next;
else lista = prossimo->next;
free(prossimo);
}
}
return b;
}
-
4) Funzione che restitisce una lista di soli veicoli con data
di immatricolazione precedente a una data inserita.
t_lista* listadata(t_lista* lista, int data) {
t_lista* prec = NULL;
t_lista* prossimo = lista;
t_lista* ret = NULL;
if (lista != NULL) {
int i = 0;
while(prossimo != NULL) {
if(prossimo->data < data) {
t_lista* ptr= (t_lista*) malloc(sizeof(t_lista));
ptr->data = prossimo->data;
ptr->peso = prossimo->peso;
strcpy(ptr->descrizione ,prossimo->descrizione);
strcpy(ptr->targa ,prossimo->targa);
strcpy(ptr->carburante ,prossimo->carburante);
ptr->next = NULL;
if(i == 0) {
// caso particolare per il primo elemento letto che è
// anche il primo elemento della lista
ret = ptr;
prec = ret;
}
else {
// il nuovo elemento letto è inserito in append (in coda)
prec->next = ptr;
prec = ptr;
}
i++;
}
prossimo = prossimo->next;
}
}
return ret;
}
-
5) Analisi del codice con istruzione fork.
main()
{
int mio_pid;
printf("Solo un processo a caso...\n");
mio_pid = fork();
if(mio_pid == 0) {
printf("il mio pid è: %d\n", mio_pid);
while(getppid() > 1) {
printf("è ancora attivo e il suo pid è: %d\n", getppid());
exit(1);
}
}
else if(mio_pid > 0) {
printf("il mio pid è %d\n", mio_pid);
sleep(10);
}
}
- Se mio_pid == 0 è il processo figlio, altrimenti è il processo padre.
- Il processo figlio finisce prima del processo padre perché già al
primo ciclo, in cui verifica la presenza del processo padre, è
presente l'istruzione exit.
Il processo padre finisce dopo perché è in attesa con sleep per
un tempo superiore al tempo di esecuzione del processo figlio.
- Il processo padre stampa il pid del processo figlio.
Il processo figlio stampa prima il proprio pid=0 e poi il pid del processo padre.