View
106
Download
1
Category
Preview:
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
Citation preview
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
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
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; }
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); }
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]); }
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]);
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);}
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.
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
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
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
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; }
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);
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 */
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);}
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;}
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.
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
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.
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’)
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();
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';
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;
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.
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;…… */
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
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;….. */
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);}
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à.
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
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
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;
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); }
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; }
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;
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]);}
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).
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
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);
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);
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) &&....” */
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"); }}
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.
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.
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
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?
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;
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; }
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);
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;
}
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);}
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.
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.
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
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];
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); }
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; }
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);
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);}
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”).
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.
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
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];
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);
}
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 ! */ }
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);
}
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 */
}
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
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
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
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.
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)
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.
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[]);
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");
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);
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);
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); }
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);}
Recommended