informatica esercizi

80
INFORMATICA Esercizi

Upload: felice

Post on 15-Jan-2016

106 views

Category:

Documents


1 download

DESCRIPTION

INFORMATICA Esercizi. Esempio: polinomi. Realizzare un programma strutturato in linguaggio C che richieda da tastiera il grado di due polinomi P1 e P2. Successivamente il programma dovrà richiedere i coefficienti dei due polinomi. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: INFORMATICA Esercizi

INFORMATICA

Esercizi

Page 2: INFORMATICA Esercizi

2 © Piero Demichelis

Esempio: polinomi

• Realizzare un programma strutturato in linguaggio C che richieda da tastiera il grado di due polinomi P1 e P2.

• Successivamente il programma dovrà richiedere i coefficienti dei due polinomi.

• Infine dovrà eseguire la somma e il prodotto dei due polinomi e visualizzare il risultato.

• Esempio:

Grado polinomio P1: 3

Grado polinomio P2: 2

 

Page 3: INFORMATICA Esercizi

3 © Piero Demichelis

Esempio: polinomi

Polinomio P1Coefficiente x^0: 2Coefficiente x^1: -3Coefficiente x^2: 1Coefficiente x^3: 2

Polinomio P2Coefficiente x^0: -1Coefficiente x^1: 2Coefficiente x^2: 2 P1: +2x^0 -3x^1 +1x^2 +2x^3P1: -1x^0 +2x^1 +2x^2 Somma: +1x^0 -1x^1 +3x^2 +2x^3Prodotto: -2x^0 +7x^1 -3x^2 -6x^3 +6x^4 +4x^5

Page 4: INFORMATICA Esercizi

4 © Piero Demichelis

Esempio: polinomi

#include <stdio.h>#include <stdlib.h> 

#define NMAX 50 

main(){int n, m, i, j;float p1[NMAX], p2[NMAX];double somma[NMAX], prodotto[2*NMAX];

/* Inizializza i due polinomi ponendo tutti i coefficienti a zero */

for (i=0; i<NMAX; i++) { p1[i] = 0; p2[i] = 0; }

Page 5: INFORMATICA Esercizi

5 © Piero Demichelis

Esempio: polinomi

/* Legge il grado dei due polinomi */

printf ("\nGrado di P1: ");scanf ("%d", &n);printf ("\nGrado di P2: ");scanf ("%d", &m);

 /* Test se il grado è positivo */if (m<1 || n<1) { printf (“\nIl grado deve essere >= 1!"); exit(2); }

Page 6: INFORMATICA Esercizi

6 © Piero Demichelis

Esempio: polinomi

/* Legge i coefficienti dei polinomi */

printf ("\nCoefficienti di P1: ");for (i=0; i<=n; i++) { printf ("\nCoefficiente x^%d: ", i); scanf ("%f", &p1[i]); } printf ("\nCoefficienti di P2: ");for (i=0; i<=m; i++) { printf ("\nCoefficiente x^%d: ",i); scanf ("%f", &p2[i]); }

Page 7: INFORMATICA Esercizi

7 © Piero Demichelis

Esempio: polinomi

 /* Calcola la somma */for (i=0; i<=max(m,n); i++) somma[i] = p1[i] + p2[i]; /* Calcola il prodotto: inizializza m+n coefficienti a 0. L'indice

del *//* vettore prodotto corrisponde al grado di quell'elemento. *//* Usa gli elementi del vettore per accumulare i risultati delle

*//* moltiplicazioni parziali */

for(i=0; i<=n+m; prodotto[i++]=0);

for(i=0; i<=n; i++) for(j=0; j<=m; j++) prodotto[i+j] = prodotto[i+j] + (p1[i] * p2[j]); 

Page 8: INFORMATICA Esercizi

8 © Piero Demichelis

Esempio: polinomi

/* Visualizzazione dei risultati */ printf ("\n\nPolinomio P1: "); for (i=0; i<=n; i++) printf ("+%fx^%d", p1[i], i); printf ("\nPolinomio P2: "); for (i=0; i<=m; i++) printf ("+%fx^%d", p2[i], i); printf ("\nSomma: "); for(i=0; i<=max(m,n); i++) printf ("+%6.2lfx^%d", somma[i], i); printf ("\nProdotto: "); for(i=0; i<=n+m; i++) printf ("+%6.2lfx^%d", prodotto[i], i);}

Page 9: INFORMATICA Esercizi

9 © Piero Demichelis

Elaborazione di una matrice

• Scrivere un programma in linguaggio C che:

legga dal file «matrice.dat» una matrice M di numeri interi preceduta dal numero di righe e dal numero di colonne (dimensione massima della matrice: 20x20)

legga da tastiera un numero intero num;

cerchi fra gli elementi della matrice il numero num, ed ogni volta che lo trova (anche più di una) scriva sul file «out.dat» tutte le sottomatrici che si ottengono da M cancellando la riga e la colonna in cui si trova num.

• I formati dei due file sono specificati nell’esempio. Si osservi che a seconda della posizione in cui si trova num, le sottomatrici possono essere una, due o quattro.

Page 10: INFORMATICA Esercizi

10 © Piero Demichelis

Elaborazione di una matrice

Esempio - File «matrice.dat»:

6 7

12 -3 1 15 24 0 41

7 34 -5 23 -7 11 10

-3 33 -4 16 63 5 -6

-2 71 2 11 95 -9 27

0 12 21 -1 7 43 10

41 15 -3 34 16 0 12

Inserisci il numero: 16

Page 11: INFORMATICA Esercizi

11 © Piero Demichelis

Elaborazione di una matrice

File «out.dat»:

Coordinate trovate: 2 3

Sottomatrici:

12 -3 1 7 34 -5

24 0 41-7 11 10

-2 71 2 0 12 2141 15 -3

95 -9 27 7 43 1016 0 12

12 -3 1 15 24 0 41 7 34 -5 23 -7 11 10-3 33 -4 16 63 5 -6-2 71 2 11 95 -9 27 0 12 21 -1 7 43 1041 15 -3 34 16 0 12

2

3

Page 12: INFORMATICA Esercizi

12 © Piero Demichelis

Elaborazione di una matrice

Coordinate trovate: 4 5

Sottomatrici:

12 -3 1 15 7 34 -5 23-3 33 -4 16-2 71 2 11 0 12 21 -1

0 41

11 10

5 -6

-9 27

43 10

12 -3 1 15 24 0 41 7 34 -5 23 -7 11 10-3 33 -4 16 63 5 -6-2 71 2 11 95 -9 27 0 12 21 -1 7 43 1041 15 -3 34 16 0 125

4

Page 13: INFORMATICA Esercizi

13 © Piero Demichelis

Elaborazione di una matrice

#include <stdio.h>#include <stdlib.h>

void sotto_matr (int r_in, int r_fin, int c_in, int c_fin);

FILE *f1, *f2;int M[20][20];

main(){int, num, rig, col, i, j, k, w;

/* apre il file contenente la matrice */if ((f1 = fopen (“matrice.dat”, "r")) == NULL) {

printf (“\nErrore nell'apertura del file matrice.dat"); return 1; }

Page 14: INFORMATICA Esercizi

14 © Piero Demichelis

Elaborazione di una matrice

/* richiede il numero da ricercare */printf (“\nInserisci un numero intero: ");scanf ("%d", &num);

/* crea il file di output */if ((f2 = fopen (“out.dat”, “w")) == NULL) {

printf (“\nErrore nella creazione del file out.dat"); return 2; }

/* legge numero di righe e colonne della matrice */fscanf (f1, "%d %d", &rig, &col);

Page 15: INFORMATICA Esercizi

15 © Piero Demichelis

Elaborazione di una matrice

/* legge il file e lo salva nella matrice M */

for (i = 0; i < rig; i++) for (j = 0; j < col; j++) fscanf (f1, "%d", &M[i][j]);

fclose(f1);

/* cerca nella matrice se esiste num controllando ogni elemento *//* della matrice tramite due for annidati; quando lo trova esegue

la *//* funzione sotto_matr per tutte le sottomatrici effettive. Ovvero *//* controlla che numero di righe o colonne della sottomatrice sia *//* maggiore di zero */

Page 16: INFORMATICA Esercizi

16 © Piero Demichelis

Elaborazione di una matrice

for (i = 0; i < rig; i++) { for (j = 0; j < col; j++) { if (M[i][j] == num) { /* trovato num: output delle coordinate */ fprintf (f2, "\nCoordinate trovate: %d %d\n\nSottomatrici:\n\n", i,

j);/* output delle matrici (se esistono) */ if ((i > 0) && (j > 0)) sotto_matr (0, i, 0, j); if ((i > 0) && (j < col – 1)) sotto_matr (0, i, j+1, col); if ((i < rig - 1) && (j > 0)) sotto_matr (i+1, rig, 0, j); if ((i < rig -1) && (j < col – 1)) sotto_matr (i+1, rig, j+1, col); } } } fclose(f2);}

Page 17: INFORMATICA Esercizi

17 © Piero Demichelis

Elaborazione di una matrice

void sotto_matr (int r_in, int r_fin, int c_in, int c_fin);{ int riga, colonna; /* scrive la matrice sul file di output */

for (riga = r_in; riga < r_fin; riga++) { for (colonna = c_in; colonna < c_fin; colonna++) fprintf (f2, "%d ", M[riga][colonna]); fprintf (f2, "\n"); } fprintf (f2,"\n"); return;}

Page 18: INFORMATICA Esercizi

18 © Piero Demichelis

Mappa

Sia data una mappa rettangolare contenente lettere dell’alfabeto. Tale mappa è memorizzata in un file di testo (il cui nome deve essere richiesto preventivamente da tastiera) in ragione di una riga per ogni linea del file.

Si supponga che non vi siano errori di formato e che le linee abbiano tutte la stessa lunghezza.

Le dimensioni della mappa non sono note in fase di compilazione, ma non possono eccedere le 20 righe per 80 colonne e devono essere dedotte dal file.

Page 19: INFORMATICA Esercizi

19 © Piero Demichelis

Mappa

A scopo di esempio, si riporta di seguito il formato di una mappa 8x8:

 

qqAAAczz

wwwcccsb

edddCDde

dddbccQw

sssdcdww

QAAzczzE

RrRqqHHi

abcdEFGH

Page 20: INFORMATICA Esercizi

20 © Piero Demichelis

Mappa

Si realizzi un programma strutturato in linguaggio C in grado di determinare quale è la sequenza di caratteri uguali disposti sulla stessa riga o sulla stessa colonna avente lunghezza massima. Le lettere maiuscole dovranno essere considerate equivalenti alle minuscole (ad esempio, ‘b’ e ‘B’, ai fini del programma, devono essere considerate la stessa lettera).

 Nel caso della mappa precedente, l’output del programma dovrà essere esattamente il seguente:

 

La sequenza più lunga si trova in colonna 5, da riga 2 a riga 6.

La disposizione è verticale

La lunghezza 5

Il carattere c.

Page 21: INFORMATICA Esercizi

21 © Piero Demichelis

Mappa

• Base dati:

la mappa verrà memorizzata in una matrice di caratteri di nome matr (vettore di stringhe).

Il numero di righe e il numero di colonne (entrambi ricavati dalla lettura del file) saranno nr e nc.

Per poter stampare i parametri richiesti occorre costruire una sequenza di variabili:

lmax = lunghezza della stringa più lunga carattere = carattere della sequenza riga = riga di inizio sequenza colonna = colonna di inizio sequenza direz = direzione della sequenza ('o‘ oppure ‘v’)

Page 22: INFORMATICA Esercizi

22 © Piero Demichelis

Mappa

#include <stdio.h>#include <string.h>#include <conio.h>

#define N_RIGHE 21#define N_COL 81 main(){ int i, j, nr, nc, cont, riga, colonna, lmax; char matr[N_RIGHE][N_COL]; FILE *leggi; char nomefile[50], carattere, cfr, direz;

clrscr();

Page 23: INFORMATICA Esercizi

23 © Piero Demichelis

Mappa

printf (“\nNome file: "); scanf ("%s", nomefile);

/* apre il file */ if ((leggi = fopen (nomefile, "r")) == NULL) { printf ("\n Errore apertura %s\n", nomefile); exit (0); }/* inizializza tutta la matrice col carattere di fine stringa */

for (i = 0; i < N_RIGHE; i++) for (j = 0; j < N_COL; j++) matr[i][j] = '\0';

Page 24: INFORMATICA Esercizi

24 © Piero Demichelis

Mappa

/* Ciclo di lettura della mappa; legge fino a EOF */ nr = 0; while (!feof (leggi)) { fscanf (leggi, "%s", &matr[nr]); nr++; /* in nr numero di righe lette */ } fclose (leggi); /* setta in nc = numero colonne matrice */ nc = strlen (matr[0]);

/* in lmax registra la lunghezza della sequenza più lunga */ lmax = 0;

Page 25: INFORMATICA Esercizi

25 © Piero Demichelis

Mappa

 /* Ricerca per righe: in cfr carattere campione da confrontare, in cont numero di ripetizioni consecutive di quel carattere */

  for (i = 0; i < nr; i++) { cfr = tolower (matr[i][0]); /* primo carattere campione = al primo

*/ cont = 1; /* carattere della riga! inoltre inizializza il contatore a 1

*//* scandisce le colonne della riga i */ for (j = 1; j <= nc; j++) { if (tolower(matr[i][j]) == cfr) /* è = al carattere campione? */ cont++; /* si, incrementa il contatore */ else/* no, è diverso per cui è terminata una sequenza la cui lunghezza è in

cont: verifica se è la più lunga finora. Contemporaneamente col carattere attuale è iniziata una nuova sequenza.

Page 26: INFORMATICA Esercizi

26 © Piero Demichelis

Mappa

{

if (cont > lmax) /* è la sequenza più lunga? */ {

lmax = cont; /* si, la sostituisce alla precedente */

carattere = cfr;

riga = i+1; /* riga di inizio sequenza */

colonna = j – cont + 1; /* colonna di inizio sequenza */

direz = 'o'; /* direzione (orizzontale) */

}

cfr = tolower (matr[i][j]); /* nuovo carattere campione */

cont = 1; } /* else….. */

} /* for (j=1; …… */

} /* for (i=0;…… */

Page 27: INFORMATICA Esercizi

27 © Piero Demichelis

Mappa

 /* Ricerca per colonne: blocco di istruzioni identico al caso della ricerca per righe scambiando solamente i ruoli delle variabili nc e nr */

for (j = 0; j <= nc; j++) { cfr = tolower (matr[0][j]); cont = 1; for (i = 1; i <= nr; i++) { if (tolower (matr[i][j]) == cfr)

cont++; else

Page 28: INFORMATICA Esercizi

28 © Piero Demichelis

Mappa

{ if (cont > lmax) { lmax = cont; carattere = cfr; riga = i - cont + 1; colonna = j + 1; direz = 'v'; } cfr = tolower(matr[i][j]); cont = 1; } /* else…… */

} /* for (i=1;……. */ } /* for (j=0;….. */

Page 29: INFORMATICA Esercizi

29 © Piero Demichelis

Mappa

 /* Visualizza i risultati */ printf ("\nSequenza più lunga "); if (direz == 'v') { printf ("in colonna %d, da riga %d a riga %d", colonna, riga, riga + lmax -1); printf ("\nLa disposizione è verticale"); } else { printf ("in riga %d, da colonna %d a colonna %d", riga,

colonna, colonna + lmax -1); printf ("\nLa disposizione è orrizzontale"); } printf ("\nLa lunghezza è %d\nIl carattere %c\n", lmax, carattere);}

Page 30: INFORMATICA Esercizi

30 © Piero Demichelis

Esempio: prenotazione aerei

• All'interno di un file di testo è elencato un insieme di voli aerei. Per ognuno di essi, su ciascuna riga del file, sono riportate (separate da un singolo spazio) la città di partenza, quella di arrivo e la sigla (2 caratteri) della compagnia aerea che gestisce il volo. E' garantito che il nome della città non contenga spazi (es. New York verrà scritto New_York).

• Si scriva un programma in linguaggio C che, ricevuto come primo argomento sulla riga di comando il nome del file e come secondo argomento il nome di una città, produca il seguente risultato sull'unità di output standard:

l’elenco dei voli in partenza dalla città l'elenco dei voli in arrivo nella città l'elenco delle compagnie aeree con voli in partenza o in arrivo

alla città selezionata.

• Il numero massimo di voli in partenza da una città (o in arrivo) non supera le 100 unità.

Page 31: INFORMATICA Esercizi

31 © Piero Demichelis

Esempio: prenotazione aerei

• Ad esempio, se il file VOLI.TXT contenesse i seguenti dati:

Roma Milano AZMilano Roma AZTorino Parigi AFParigi Torino AFMilano Londra BALondra Milano BAMilano New York AZMilano New York UANew York Milano AZNew York Milano UA

e il programma - denominato FLY - venisse attivato nel seguente modo:

FLY VOLI.TXT Milano

Page 32: INFORMATICA Esercizi

32 © Piero Demichelis

Esempio: prenotazione aerei

allora dovrebbe generarsi il seguente output:

Voli in partenza da Milano:Milano Roma AZMilano Londra BAMilano New_York AZMilano New_York UA

Voli in arrivo a Milano:Roma Milano AZLondra Milano BANew_York Milano AZNew_York Milano UA  

Compagnie aeree:AZBAUA

Page 33: INFORMATICA Esercizi

33 © Piero Demichelis

Esempio: prenotazione aerei

#include <stdio.h>#include <stdlib.h>#include <string.h>

#define MAXVOLI 100

typedef enum{FALSO,VERO} boolean;

int main(int argc, char *argv[ ]){ char tab_arrivi[MAXVOLI][80], compagnie[MAXVOLI][3]; int num_arrivi,num_comp,i; char partenza[80], arrivo[80], compagnia[3], citta[20]; boolean trovato, presente; FILE *in;

Page 34: INFORMATICA Esercizi

34 © Piero Demichelis

Esempio: prenotazione aerei

/* Controlli sulla correttezza del numero di parametri introdotto */

/* dalla linea di comando */

if (argc != 3) { printf ("\nErrore: imposta come parametri nome file e città\n"); exit (1); }/* apre il file dei voli */ if ((in=fopen(argv[1],"r"))==NULL) { printf ("\nErrore in apertura file\n"); exit (2); }

Page 35: INFORMATICA Esercizi

35 © Piero Demichelis

Esempio: prenotazione aerei

strcpy (citta, argv[2]); /* argv[2] in citta */

num_arrivi = 0; num_comp = 0;

printf ("\nVoli in partenza da %s:\n\n", citta);

while (!feof(in)) { fscanf (in, "%s %s %s", partenza, arrivo, compagnia) trovato = FALSO;

/* controlla la partenza */ if (strcmp (partenza, citta)==0) { printf ("%s %s %s\n", partenza, arrivo, compagnia); trovato = VERO; }

Page 36: INFORMATICA Esercizi

36 © Piero Demichelis

Esempio: prenotazione aerei

/* controlla l'arrivo */ if (strcmp (arrivo,citta)==0) { sprintf (tab_arrivi[num_arrivi], "%s %s %s",

partenza, arrivo, compagnia); num_arrivi++; trovato = VERO;

} /* controlla se la compagnia è già presente nella lista */ if (trovato)

{ presente = FALSO; for (i=0; i<num_comp; i++)

if (strcmp(compagnia, compagnie[i]) == 0) presente = VERO;

Page 37: INFORMATICA Esercizi

37 © Piero Demichelis

Esempio: prenotazione aerei

if (!presente) { strcpy(compagnie[num_comp], compagnia); num_comp++; }

} } /* fine while */

/* Elenca i voli in arrivo e le compagnie accumulati nei vettori di *//* stringhe tab_arrivi e compagnie in precedenza */ printf ("\n\nVoli in arrivo a %s:\n\n", citta);  for (i=0; i<num_arrivi; i++) printf ("%s\n", tab_arrivi[i]);

printf ("\n\nCompagnie che operano a %s:\n\n", citta); for (i=0; i<num_comp; i++) printf ("%s\n", compagnie[i]);}

Page 38: INFORMATICA Esercizi

38 © Piero Demichelis

Compressione di immagini

• Scrivere un programma in linguaggio C per la compressione di immagini che:

legga dal file «matrice.dat» una matrice di numeri reali di dimensione 30x30;

legga da tastiera due numeri interi N e M che rappresentano le dimensioni di una sottomatrice;

• suddivida la matrice in sottomatrici NxM a partire dall’elemento in alto a sinistra, e costruisca una nuova matrice 30x30 di numeri reali, in cui ogni elemento delle sottomatrici è dato dalla media degli elementi della sottomatrice stessa (vedere esempio);

• visualizzi su video la matrice finale.

• Importante: vicino al bordo destro e inferiore è possibile che le sottomatrici da considerare abbiamo dimensioni inferiori a NxM (vedere esempio).

Page 39: INFORMATICA Esercizi

39 © Piero Demichelis

Compressione di immagini

• Esempio: Con N= 2, M=4:File «matrice.dat» (per semplicità sia 6x6):1 0 1 2 3 42 3 2 3 0 50 2 1 2 4 31 2 2 2 1 01 5 4 3 2 12 1 2 0 7 0 media = 1.75

Matrice finale :1.75 1.75 1.75 1.75 3.0 3.01.75 1.75 1.75 1.75 3.0 3.01.5 1.5 1.5 1.5 2.0 2.01.5 1.5 1.5 1.5 2.0 2.02.25 2.25 2.25 2.25 2.5 2.52.25 2.25 2.25 2.25 2.5 2.5

Page 40: INFORMATICA Esercizi

40 © Piero Demichelis

Compressione di immagini

#include <stdio.h>#include <stdlib.h>

#define DIM 30

main(){float mat[DIM][DIM], som, med;int N, M, i, j, k, rig, col;FILE *f1;

printf ("\nInserisci il numero di righe N: ");scanf ("%d",&N);printf ("\nInserisci il numero di colonne M: ");scanf ("%d",&M);

Page 41: INFORMATICA Esercizi

41 © Piero Demichelis

Compressione di immagini

/* apre il file matrice.dat */

if ((f1 = fopen ("matrice.dat","r")) == NULL); { printf (“\nErrore apertura di matrice.dat\n”); return (1); }

/* legge il file matrice.dat ritenuto corretto, pertanto non ci sono */

/* controlli sui valori letti */

for (i = 0; i < DIM; i++) for (j = 0; j < DIM; j++) fscanf (f1, "%f", &mat[i][j]);

fclose(f1);

Page 42: INFORMATICA Esercizi

42 © Piero Demichelis

Compressione di immagini

/* individua riga e colonna iniziale di tutte le possibili sottomatrici */

for (rig = 0; rig < DIM; rig += N) { for (col = 0; col < DIM; col += M) { /* per ognuna calcola il valor medio */ k = 0; som = 0; for (i = rig; i < (N + rig) && i < DIM; i++) { for (j = col; j < (M + col) && j < DIM; j++) { k++; som += mat[i][j]; } /* fine “for (j = col; j < (M + col) &&....” */

} /* fine “for (i = rig; i < (N + rig) &&....” */

Page 43: INFORMATICA Esercizi

43 © Piero Demichelis

Compressione di immagini

/* costruisce la nuova sottomatrice sostituendo ai valori precedenti */

/* il valor medio appena calcolato */ med = som / k;

for (i = rig; i < (N + rig) && i < DIM; i++) for (j = col; j < (M + col) && j < DIM; j++) mat[i][j] = med; } /* fine “for (col = 0; col < DIM; col += M)” */} /* fine “for (rig = 0; rig < DIM; rig += N)” *//* visualizza la nuova matrice */for (i = 0; i < DIM; i++) { for (j = 0; j < DIM; j++) printf ("%.2f ", mat[i][j]); printf ("\n"); }}

Page 44: INFORMATICA Esercizi

44 © Piero Demichelis

Gestione di un bar

• Si desidera realizzare un programma in linguaggio C che consenta di gestire i conti dei clienti di un bar. Il programma permette di inserire da tastiera il codice numerico di ognuna delle consumazioni di un cliente.

• Il codice 0 indica che l’inserimento è finito e che il programma deve stampare il conto; il conto stampato dal programma contiene la descrizione e il costo di ognuna delle consumazioni, nonché l’importo totale dovuto dal cliente.

• Si noti che il codice 0 non implica la fine del programma, il quale deve invece ritornare all’inizio dell’inserimento di un nuovo conto. Il programma termina quando viene introdotto il codice –1.

Page 45: INFORMATICA Esercizi

45 © Piero Demichelis

Gestione di un bar

• La corrispondenza tra il codice di una consumazione e un articolo si trova in un primo file il cui nome viene specificato come primo parametro sulla linea di comando. Nel file i codici (e i relativi articoli) sono elencati in ordine a partire dal codice 1 (vedi esempio).

• La corrispondenza tra un articolo ed il suo prezzo si

trova in un secondo file il cui nome viene specificato come secondo parametro sulla linea di comando.

• Si facciano inoltre le seguenti assunzioni:

Ciascun conto consiste al massimo di 10 consumazioni Sono previsti al massimo 100 articoli diversi.

Page 46: INFORMATICA Esercizi

46 © Piero Demichelis

Gestione di un bar

• Esempio:

• Supponendo che il file CODICI.DAT contenga i seguenti dati:1 Birra_Media2 Birra_Piccola3 Panino4 Coca_Cola5 Acqua_Minerale 

e che il file PREZZI.DAT contenga i seguenti dati:Panino 3.50Coca_Cola 2.00Birra_Media 4.00Birra_Piccola 2.50Acqua_Minerale 1.00

Page 47: INFORMATICA Esercizi

47 © Piero Demichelis

Gestione di un bar

• Invocando il programma di nome CONTO con il seguente comando:

CONTO CODICI.DAT PREZZI.DAT

• Inserendo i seguenti dati,

Consumazione? 1Consumazione? 5Consumazione? 1Consumazione? 0

  il programma produrrà il seguente output:Birra_Media 4.00Panino 3.50Birra_Media 4.00 

Totale 11.50 Euro.Consumazione?

Page 48: INFORMATICA Esercizi

48 © Piero Demichelis

Gestione di un bar#include <stdio.h>

typedef enum {FALSO, VERO} boolean;

typedef struct {char articolo[30];float costo;

} prodotti;

void stampa_output (prodotti v[], int n, float tot)

int main (int argc, char *argv[]){ prodotti consumazione[10], articoli[101]; float totale_cons = 0.0, costo; int i, artic = 0, codice, cod, N_articoli = 0; char prodotto[30]; boolean trovato; FILE *fp1, *fp2;

Page 49: INFORMATICA Esercizi

49 © Piero Demichelis

Gestione di un bar

if(argc != 3) /* controllo argomenti */ { printf ("errore parametri\n"); return 1; }

if ((fp1 = fopen (argv[1],"r")) == NULL) {

fprintf (stderr,"Errore nell'apertura del file %s\n", argv[1]); return 2; } if ((fp2 = fopen (argv[2],"r")) == NULL) {

fprintf (stderr,"Errore nell'apertura del file %s\n", argv[2]); return 3; }

Page 50: INFORMATICA Esercizi

50 © Piero Demichelis

Gestione di un bar

/* riempimento del vettore di strutture articoli */ while (fscanf (fp1,"%d%s", &cod, prodotto) != EOF) {

strcpy (articoli[cod].articolo, prodotto); N_articoli++; } fclose (fp1);/* Legge il costo dei prodotti e li salva nel campo di pertinenza */ while (fscanf (fp2,"%s%f", prodotto, &costo) != EOF) { /* cerco nel vettore di strutture */ i = 1; trovato = FALSO; while (!trovato && (i <= N_articoli)) { if (strcmp (prodotto, articoli[i].articolo) == 0) { articoli[i].costo = costo; trovato = VERO; } i++; } } fclose(fp2);

Page 51: INFORMATICA Esercizi

51 © Piero Demichelis

Gestione di un bar

/* inizio parte interattiva */ printf (“\nConsumazione? "); scanf ("%d", &codice);

while (codice != -1) {

if (codice == 0) {

stampa_output (consumazione, artic, totale_cons); artic = 0; /* inizializzazioni per prossimo conto

*/ totale_cons = 0.0; } else { consumazione[artic] = articoli[codice]); artic++; totale_cons += articoli[codice].costo;

}

Page 52: INFORMATICA Esercizi

52 © Piero Demichelis

Gestione di un bar

printf ("\nConsumazione? "); /* leggi un altro codice */ scanf ("%d", &codice); } /* fine del ciclo while (c!= -1)...... */} /* fine del main*/

void stampa_output (prodotti v[], int n, float tot){ int i;

for (i=0; i<n; i++) printf ("%s %f\n", v[i].articolo, v[i].costo);

printf ("Totale %f\n", tot);}

Page 53: INFORMATICA Esercizi

53 © Piero Demichelis

Esempio: supermercato

• Gli acquisti effettuati in un piccolo supermercato sono registrati e memorizzati in un file di caratteri costituito da un numero di righe indefinito. Ciascuna riga ha il seguente formato:

prodotto categoria valore

• in cui: prodotto indica il nome del prodotto acquistato, categoria indica una suddivisione in categorie dei prodotti (e.g., alimentari, vestiario, etc.), valore indica la cifra spesa (e.g., in lire o euro) per l'acquisto dello stesso.

• Il prodotto e la categoria sono individuati da stringhe di caratteri (non contenenti spazi) e di lunghezza massima uguale a 50 e 3 caratteri rispettivamente; valore è un numero intero.

Page 54: INFORMATICA Esercizi

54 © Piero Demichelis

Esempio: supermercato

• Si richiede la scrittura di un programma in linguaggio C che produca un secondo file contenente delle statistiche sugli acquisti, suddivise per categoria (i.e., ciascuna categoria deve comparire nel file una sola volta). Ciascuna riga del file deve avere il seguente formato:

categoria numero valore-totale valore-medio

• in cui: numero indica il numero totale di acquisti per la relativa categoria, valore-totale la somma totale dei valori per quella categoria, e valore-medio la cifra media spesa per quella categoria in ciascun acquisto. Tutti i valori numerici devono essere riportati quali interi.

• I nomi dei due file devono essere letti da tastiera, il file di ingresso si può supporre di formato corretto, il numero massimo di categorie è uguale a 100, l'ordine di memorizzazione nel file di uscita delle varie categorie può essere qualsiasi.

Page 55: INFORMATICA Esercizi

55 © Piero Demichelis

Esempio: supermercato

Esempio.

• Supponendo che il file di ingresso abbia il seguente formato

pastaXYZ ali 8000pannolini123 mis 30000paneAAA ali 2500jeansBBB ves 85000scarpeCCC ves 45000olioXYWZ ali 12500

• occorre produrre il seguente file

ali 3 23000 7667ves 2 130000 65000mis 1 30000 30000

Page 56: INFORMATICA Esercizi

56 © Piero Demichelis

Esempio: supermercato

#include <stdio.h>#include <stdlib.h>#include <string.h>

#define MAX 100

typedef enum {FALSO,VERO} boolean;

main(){char nomefile[80];struct cate { char nome[4]; long num; long val; } categorie[MAX];

Page 57: INFORMATICA Esercizi

57 © Piero Demichelis

Esempio: supermercato

FILE *in,*out;long ncat = 0, val, i;boolean trovato;char cat[4], prod[51];

/* Richiede nome file */printf ("\nNome file aquisti: ");scanf ("%s", nomefile); /* Apre il file */if ((in = fopen(nomefile, "r")) == NULL) { printf ("\nErrore open\n"); exit (1); }

Page 58: INFORMATICA Esercizi

58 © Piero Demichelis

Esempio: supermercato

/* Legge il file riga per riga e cerca se la categoria è già presente */

while (!feof (in)) { fscanf (in, "%s %s %ld", prod, cat, &val) trovato = FALSO; i = 0; while (!trovato && (i < ncat)) if (strcmp(categorie[i].nome, cat) == 0) { /* categoria già vista prima: aggiorna i campi */

categorie[i].num++; categorie[i].val += val; trovato = VERO; }

Page 59: INFORMATICA Esercizi

59 © Piero Demichelis

Esempio: supermercato

/* categoria nuova, aggiunge un nuovo elemento al vettore di */

/* strutture per l’output finale */ if (!trovato) { strcpy (categorie[ncat].nome, cat); categorie[ncat].num = 1; categorie[ncat].val = val; ncat++; } } fclose(in);/* Chiede il nome file di output e lo crea */printf ("\nNome file output: ");scanf ("%s", nomefile);

Page 60: INFORMATICA Esercizi

60 © Piero Demichelis

Esempio: supermercato

if ((out = fopen(nomefile,"w")) == NULL)

{ printf ("\nErrore open\n"); exit (3); }

/* Scrive sul file di output i dati richiesti */ for (i=0; i<ncat; i++) fprintf (out,"%s %ld %ld %ld\n", categorie[i].nome, categorie[i].num, categorie[i].val,

categorie[i].val/categorie[i].num); fclose(out);}

Page 61: INFORMATICA Esercizi

61 © Piero Demichelis

Crittografia

Si desidera realizzare un programma in linguaggio C a cui vengono forniti come parametri sulla riga di comando due nomi di file e un numero intero N maggiore di zero.

Il primo file contiene un testo in formato ASCII, e consiste di un numero indefinito di righe ciascuna formata al massimo da 80 caratteri.

Il programma deve crittografare il contenuto del primo file e scriverlo nel secondo file, anch'esso in formato ASCII.

Il metodo crittografico considerato funziona nel seguente modo: ogni lettera maiuscola e minuscola dell'alfabeto deve essere sostituita con la lettera dell'alfabeto stesso che si ottiene spostandosi di N posizioni in ordine alfabetico crescente, partendo dalla lettera che si vuole crittografare. Ad esempio se N=5 e il carattere da crittografare è il carattere “m”, il carattere crittografato sarà “r” (5 posizioni nell’ordine alfabetico dopo la “m”).

Page 62: INFORMATICA Esercizi

62 © Piero Demichelis

Crittografia

Lo spostamento deve essere effettuato in modo “circolare”: Se nello spostamento, dalla lettera considerata, si supera la fine dell'alfabeto, si deve ripartire a contare dall’inizio. Ad esempio, se N=1, e il carattere da crittografare è "z" il carattere da scrivere nel secondo file sarà il carattere "a".

A sostituzione avvenuta, la riga crittografata deve essere scritta invertita nel secondo file (cioè l'ultimo carattere diventa il primo, il penultimo diventa il secondo e così via).

Tutti gli altri caratteri (punteggiatura, spaziatura) rimangono inalterati.

NOTE:- Si consiglia di processare un carattere per volta usando le opportune funzioni di interrogazione dell’insieme dei caratteri ASCII.

Page 63: INFORMATICA Esercizi

63 © Piero Demichelis

Crittografia

Esempio di esecuzione:

Supponendo di avere N=1 e che il contenuto del file di input sia:

Questo compito e’ facilissimo!Vero?

Nel file di output dovrà esserci scritto:

!pnjttjmdbg ‘f pujpnpd putfvR?psfW

Page 64: INFORMATICA Esercizi

64 © Piero Demichelis

Crittografia

#include <stdio.h>#include <string.h>#include <ctype.h>

#define DIM 80

/* prototipo */void inverti (char s[]);

/* main */

int main (int argc, char *argv[]){

FILE *fin, *fout;int i, N, val;char lineain[DIM], lineaout[DIM];

Page 65: INFORMATICA Esercizi

65 © Piero Demichelis

Crittografia

if (argc != 4) {

printf ("Errore di formato dei parametri!\n");exit (0);

}

if ((fin = fopen (argv[1], "r")) == NULL){

printf ("Errore nell'apertura del file %s\n", argv[1]);exit (0);

}

if ((fout = fopen (argv[2], "w")) == NULL){

printf ("Errore nell'apertura del file %s\n", argv[2]);exit (0);

}

Page 66: INFORMATICA Esercizi

66 © Piero Demichelis

Crittografia

N = atoi (argv[3]);/* legge una linea alla volta e poi inverte la stringa crittografata */while (fgets (lineain, DIM, fin) != NULL) { /* ora processa carattere per carattere */ for (i=0; i<strlen (lineain); i++) { /* processa solo i caratteri alfabetici */

if (isalpha (lineain[i])) { /* devo sommare N al codice ASCII */

if (islower(lineain[i])) val = lineain[i]-'a'; else val = lineain[i]-'A';

val = ((val + N) % 26); /* somma 'circolare‘: ci sono 26 caratteri *//* ritrasformo 'val' in un carattere ASCII */ if (islower(lineain[i])) lineaout[i] = val + 'a'; else lineaout[i] = val + 'A';/* NOTA: non e' l'unico modo per sommare N ! */ }

Page 67: INFORMATICA Esercizi

67 © Piero Demichelis

Crittografia

else /* non è un carattere alfabetico, quindi lo scrive invariato */

lineaout[i] = lineain[i];} /* chiusura di for (i=0; i<strlen (lineain);….. */

/* finito il processamento della linea 'lineain‘, ora la inverto e la *//* scrivo sul file 'fout'. Prima pero' devo aggiungere il NULL se no *//* non e' una stringa! */ lineaout[i] = '\0'; inverti (lineaout); puts (lineaout); /* visualizza anche sul monitor (non richiesto) */ fputs (lineaout, fout); fprintf (fout, “\n”); } /* chiusura di while (fgets(lineain, DIM, fin)…… */

fclose (fin);fclose (fout);

}

Page 68: INFORMATICA Esercizi

68 © Piero Demichelis

Crittografia

void inverti (char s[]){

int i, len = strlen(s);char tmp;

for (i=0; i < len/2; i++) {/* scambio i valori i e N-i-1 */

tmp = s[i];s[i] = s[len-i-1];s[len-i-1] = tmp;

}

/* nota: s viene passata per indirizzo (e' un vettore) e pertanto */

/* viene ritornata al main modificata */

}

Page 69: INFORMATICA Esercizi

69 © Piero Demichelis

Import / Export

• Sono dati tre file di testo contenenti le informazioni sulle operazioni di una ditta di import/export, che ha relazioni commerciali con società appartenenti a vari stati.

• Un primo file (il cui nome è STATI.DAT) contiene l’elenco degli stati (al massimo 100) con cui esistono relazioni commerciali, nel seguente formato:

<codice_stato> <nome_stato>dove <codice_stato> è un codice numerico progressivo (un numero intero: 0 per il primo stato, 1 per il secondo, …), mentre <nome_stato> è il nome dello stato, privo di spazi.

Esempio:0 Stati_Uniti1 Corea2 Giappone3 Francia4 Germania

Page 70: INFORMATICA Esercizi

70 © Piero Demichelis

Import / Export

• Un secondo file (il cui nome DITTE.DAT) contiene l’elenco delle ditte (al massimo 1000) , con cui esistono relazioni commerciali, nel seguente formato:

<codice_stato> <nome_societa>

dove <codice_stato> è il codice dello stato cui appartiene la società, <nome_societa> è il nome della società.

Esempio:

1 Kia 2 Honda

4 BMW 2 Mitsubishi

4 Mercedes 0 Chrysler

3 Peugeot 0 General_Motors

3 Citroen 0 Chevrolet

Page 71: INFORMATICA Esercizi

71 © Piero Demichelis

Import / Export

• Un terzo file (il cui nome è TRANSAZIONI.DAT) contiene le informazioni su un certo numero di transazioni commerciali, ognuna delle quali viene rappresentata, su una riga del file, secondo il formato:

<nome_societa> <importo> <data> dove <nome_società> è il nome della società, <importo> è un intero, che rappresenta l’importo della transazione (valore negativo per importazione, positivo per esportazione), <data> è la data della transazione (formato gg/mm/aaaa).

Esempio:

Mitsubishi 101 21/01/2004 Mercedes 300 23/06/2004Chrysler -30 01/02/2004 Peugeot 403 02/07/2004 General_Motors -2000 10/02/2004 General_Motors 1124 05/07/2004Chevrolet 50 04/03/2004 Chevrolet 350 10/08/2004Kia 500 12/03/2004 Citroen -325 11/08/2004BMW -1200 15/04/2004 Honda -670 30/08/2004Mercedes -400 23/04/2004 Peugeot -768 21/09/2004BMW -1000 22/06/2004 Kia -800 23/09/2004

Page 72: INFORMATICA Esercizi

72 © Piero Demichelis

Import / Export

• Si scriva un programma in linguaggio C che legga ed elabori i dati secondo le richieste seguenti.

• Calcoli il numero totale delle transazioni e i bilanci complessivi delle transazioni di importazione e esportazione (somma degli importi relativi, rispettivamente, a importazioni ed esportazioni), che vanno stampati su video.

• Calcoli per ogni stato, il bilancio complessivo commerciale di import/export (cioé la sommatoria, per ogni stato, degli importi relativi a tutte le società appartenenti allo stato). Per ogni stato vanno stampati su video il nome e il bilancio totale.

Page 73: INFORMATICA Esercizi

73 © Piero Demichelis

Import / Export

• Sulla base di questi dati, l’output del programma sarà il seguente:

Numero transazioni: 16Totale importazioni: -7193Totale esportazioni: 2828

STATO: Stati_Uniti BILANCIO: -506 (ottenuto come: -30-2000+50+1124+350)STATO: Corea BILANCIO: -300

(ottenuto come: 500-800)STATO: Giappone BILANCIO: -569

(ottenuto come: 101-670)STATO: Francia BILANCIO: -690

(ottenuto come: 403-325-768)STATO: Germania BILANCIO: -2300

(ottenuto come: -1200-400-1000+300)

Page 74: INFORMATICA Esercizi

74 © Piero Demichelis

Import / Export

Per semplicità non devono essere eseguiti controlli di errore sul formato dei file, sugli argomenti al main, sull'apertura corretta dei file.

La soluzione proposta prevede due tipi struct (t_stato e t_societa) per le informazioni relative, rispettivamente, a stati e società. I primi due file vengono infatti letti caricando i dati un due vettori di struct (tabella_stati e tabella_societa). Il codice di uno stato non viene inserito nella struttura t_stato in quanto coincide con l'indice dello stato stesso nel vettore (0 per il primo stato, 1 per il secondo, ...). Per i dati nel terzo file non sono previste tabelle, in quanto non è necessario disporre di tutte le informazioni (su tutte le transazioni) contemporaneamente: il file viene letto riga per riga aggiornando le statistiche sulle transazioni (globali e per stato) mediante i dati appena letti: le date vengono lette ma ignorate, in quanto non necessarie alla soluzione del problema.

Page 75: INFORMATICA Esercizi

75 © Piero Demichelis

Import / Export

#include <stdio.h>

/* tipi struct per stato e societa' */

typedef struct { char nome[30]; int bilancio;} t_stato;

typedef struct { char nome[30]; int codice_stato;} t_societa;

/* prototipo di funzione */int cercaCodiceStato (t_societa tabella_societa[], int n, char nome[]);

Page 76: INFORMATICA Esercizi

76 © Piero Demichelis

Import / Export

int main (void){ FILE *fp; int i, nst, nsoc; int codice_stato, importo; int nt, si, se; /* num. trans., importazioni, esportazioni

*/ char nome[30]; t_stato tabella_stati[100]; t_societa tabella_societa[1000]; /* lettura file stati.dat: tabella stati */ fp = fopen ("stati.dat","r");

Page 77: INFORMATICA Esercizi

77 © Piero Demichelis

Import / Export

nst=0; while (fscanf(fp,"%d%s", &codice_stato, nome)!=EOF) { nst++; strcpy (tabella_stati[codice_stato].nome,nome); tabella_stati[codice_stato].bilancio = 0; } fclose(fp);

/* lettura file ditte.dat: tabella societa' */ fp = fopen ("ditte.dat", "r"); nsoc = 0; while (fscanf(fp,"%d%s", &codice_stato, nome) != EOF) { strcpy (tabella_societa[nsoc].nome, nome); tabella_societa[nsoc].codice_stato = codice_stato; nsoc++; } fclose(fp);

Page 78: INFORMATICA Esercizi

78 © Piero Demichelis

Import / Export

/* Lettura transazioni.dat ed elaborazione dei dati. Per ogni riga del file transazioni.dat, letti nome della societa e importo, si aggiornano gli importi totali e di import/export. Si calcola quindi il codice dello stato (mediante la funzione cercaCodiceStato, quindi si aggiorna la statistica di bilancio totale relativa allo stato. */

fp = fopen ("transazioni.dat", "r"); nt = si = se = 0; while (fscanf (fp,"%s%d%*s", nome, &importo) != EOF) { nt++; if (importo > 0) se += importo; else si += importo; i = cercaCodiceStato (tabella_societa, nsoc, nome); tabella_stati[i].bilancio += importo; } fclose(fp);

Page 79: INFORMATICA Esercizi

79 © Piero Demichelis

Import / Export

/* stampa statistiche globali */

printf ("Numero transazioni: %d\n", nt); printf ("Totale importazioni: %d\n", si); printf ("Totale esportazioni: %d\n\n", se);

/* stampa statistiche per stato */

for (i=0; i<nst; i++) printf ("STATO: %-30s BILANCIO: %8d\n", tabella_stati[i].nome,

tabella_stati[i].bilancio); }

Page 80: INFORMATICA Esercizi

80 © Piero Demichelis

Import / Export

/* funzione che cerca il codice dello stato cui appartiene una societa', dato il nome di quest'ultima. La ricerca viene fatta nella tabella delle societa'. */

int cercaCodiceStato ( t_societa tabella_societa[], int n, char nome[])

{ int i; for (i=0; i<n; i++) { if (strcmp (tabella_societa[i].nome, nome) == 0) index = tabella_societa[i].codice_stato; } return (index);}