Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di...

39
1 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione Fondamenti di Programmazione - Università degli Studi di Brescia Ingegneria dellAutomazione Industriale Ingegneria Elettronica e delle Comunicazioni Alessandro Saetti Marco Sechi e Andrea Bonisoli (email: {alessandro.saetti,marco.sechi,andrea.bonisoli}@unibs.it) Università degli Studi di Brescia A.A. 2013/2014

Transcript of Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di...

Page 1: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

1 A.A. 2013/2014 Docente: A. Saetti

Fondamenti di Programmazione

Fondamenti di Programmazione - Università degli Studi di Brescia

Ingegneria dell’Automazione Industriale Ingegneria Elettronica e delle Comunicazioni

Alessandro Saetti Marco Sechi e Andrea Bonisoli

(email: {alessandro.saetti,marco.sechi,andrea.bonisoli}@unibs.it)

Università degli Studi di Brescia A.A. 2013/2014

Page 2: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

2 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizi sull’uso di file testuali

1.  Scrivere un programma C che visualizzi il contenuto del file di testo “lab1.txt”, convertendo in maiuscole tutte le lettere presenti nel file (i caratteri che non rappresentano delle lettere non dovranno essere modificati).

2.  Scrivere un programma C che visualizzi i 10 numeri interi contenuti nel file binario lab2.dat e successivamente sovrascriva il file invertendo l’ordine dei numeri.

Page 3: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

3 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1 Scrivere un programma C che visualizzi il contenuto del file di testo “lab1.txt”, convertendo in maiuscole tutte le lettere presenti nel file (i caratteri che non rappresentano delle lettere non dovranno essere modificati).

Contenuto  di  Lab1.txt  

Page 4: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

4 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1 Esercizi sull’uso dei file testuali (1°parte)

/************************************************************************** * Nome: lab1-maiuscole.c * * Autore: Alessandro Saetti * * Data: 6/4/10 *

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

/* Nome: main * Scopo: Converte i caratteri da minuscolo a maiuscolo * Input: int argc: il numero di argomenti specificati da linea di comando * char *argv: la linea di comando che contiene il nome del file da convertire * Output: 0 se il programma termina correttamente */

int main() {

system("pause"); return 0; }

 Scrivere  un  programma  C  che  visualizzi  il  contenuto  del  file  di  testo  “lab1.txt”,  convertendo  in  maiuscole  tu8e  le  le8ere  presen:  nel  file  (i  cara8eri  che  non  rappresentano  delle  le8ere  non  dovranno  essere  modifica:).

Impos4amo  la  solita  stru7ura  iniziale    di  un  programma  C,  aggiungendo  eventuali  commen4  

//  Soluzione  richiesta  

Page 5: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

5 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1 Esercizi sull’uso dei file testuali (1°parte)

Nel  main()  

char str[DIM]; FILE *fp;

Inseriamo  nel  main()  il  codice  rela4vo  all’apertura  e  alla  le7ura,  riga  per  riga,  del  file  “lab1.txt”.  U4lizziamo  un’opportuna  #define  per  indicare  il  numero  massimo  di  cara7eri  per  riga.  

Aggiungiamo,  man  mano,  le  variabili  necessarie:  -­‐  la  variabile  str  conterrà  le  righe  via  via  le8e;    -­‐  il  puntatore  fp  alla  stru8ura  FILE  consen:rà    la  ges:one  del  file  passato  come  argomento  sulla  linea  di  comando  

#define DIM 50

Al  termine  chiudo  il  file  

while(feof(fp) == 0) { if (fgets(str, DIM, fp) != NULL) {

} }

fp = fopen("lab1.txt", "r"); if (fp == NULL) { printf("\nErrore apertura file!\n");

exit(0); }

Finchè  non  sono  in  fondo  al  file  [feof(fp)==0]    leggo  e  carico  nell’array  str[]  le  righe  presen:  nel  file.    Una  riga,  in  questo  esercizio,  è  una  sequenza  di  al    massimo  50  cara8eri  terminata  eventualmente  con  l’invio  ‘\n’.  

Apro  in  le8ura  il  file  richiesto.  Se  non  esiste    segnalo  l’errore  e  termino  il  programma  

L’apertura  di  un  file  viene  realizzata  mediante  la  funzione  fopen().  Se  si  verifica  un  errore  fopen()  res4tuisce  un  puntatore  nullo  (NULL).

 Scrivere  un  programma  C  che  visualizzi  il  contenuto  del  file  di  testo  “lab1.txt”,  convertendo  in  maiuscole  tu8e  le  le8ere  presen:  nel  file  (i  cara8eri  che  non  rappresentano  delle  le8ere  non  dovranno  essere  modifica:).

fclose(fp);

//  Lascio  in  sospeso  la  trasformazione  in  //  maiuscolo  della  stringa  corrente  appena  leHa  

Il  2^  argomento  di  fopen  indica  la  modalità  di  apertura

Page 6: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

6 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1 Esercizi sull’uso dei file testuali (1°parte)

Nel  main()  

char str[DIM]; FILE *fp; int i;

Aggiungiamo  nel  main()  il  codice  che  trasforma  ogni  singolo  cara7ere  alfabe4co  minuscolo,  contenuto  nel  file,    nel  corrispondente  simbolo  maiuscolo.  

Aggiungiamo  ulteriori  variabili  

While (feof(fp) == 0) { if (fgets(str, DIM, fp) != NULL) {

for (i =0 ; i < DIM && str[i]!='\0'; i++) if (str[i] >= 'a' && str[i] <= 'z')

printf("%c", str[i] - 'a' + 'A'); else printf("%c", str[i]); }

}

Scorro  i  cara8eri  in  str[]  uno  per  uno  e  se  si  tra8a  di    le8ere  minuscole  (str[i]<=‘z’  &&  str[i]>=’a’)  so8raggo  la  “distanza  Ascii”  (‘A’-­‐’a’)  tra  i  simboli  minuscoli  e  quelli  maiuscoli.  

 Scrivere  un  programma  C  che  visualizzi  il  contenuto  del  file  di  testo  “lab1.txt”,  convertendo  in  maiuscole  tuHe  le  leHere  presenL  nel  file  (i  caraHeri  che  non  rappresentano  delle  leHere  non  dovranno  essere  modificaL).

//  Trasformazione  in  maiuscolo  della  stringa  

‘a’-­‐’A’  (u4lizzando  la  codifica  ASCII)  corrisponde  a  32  (97  –  65).  Tale  valore    corrisponde  alla  “distanza  Ascii”  tra  i  cara7eri  minuscoli  e  quelli  maiuscoli.  InfaQ  se  ad  un  simbolo  minuscolo  so7raggo  tale  valore  o7engo  il  corrispondente  simbolo  maiuscolo

//  Codice  C  relaLvo  all’apertura  del  file  

TABELLA  ASCII  

Page 7: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

7 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1 Esercizi sull’uso dei file testuali (1°parte)

Una  soluzione  alterna4va,  che  evita  l’uso  dell’array  str[]  (necessario  per  la  le7ura  riga  per  riga),    può  essere  o7enuta  leggendo  il  file  lab1.txt  cara7ere  per  cara7ere.  In  questo  caso  occorre  usare  la  funzione  fgetc()  oppure  fscanf().  

While (feof(fp) == 0) { if (fgets(str, DIM, fp) != NULL) {

for (i =0 ; i < DIM && str[i]!='\0'; i++) if (str[i] >= 'a' && str[i] <= 'z') printf("%c", str[i] - 'a' + 'A');

else printf("%c", str[i]); } }

while(feof(fp) == 0) { // in alternativa a fgetc // if (fscanf(fp, "%c", &c) != EOF) if ((c = fgetc(fp)) != EOF)

{ if (c >= 'a' && c <= 'z') printf("%c", c - 'a' + 'A');

else printf("%c", c); } }

SOLUZIONE  ALTERNATIVA  

La  funzione  fgetc  acquisisce  il  cara7ere  corrente  dello  stream  puntato  da  fp  e  sposta  in  avan4  di  un  byte  l'indice  di  posizione  dello  stream  stesso.  Se  la  le7ura  ha  successo  la  funzione  res4tuisce  il  cara7ere  le7o  c.  Quando  arrivo  alla  fine  del  file  fgetc  res4tuisce  il  cara7ere  EOF  e  l'indicatore  res4tuito  da  feof()  viene  posto  a  true.  Se  invece  si  verifica  un  errore  viene  se7ato  l'indicatore  di  errore  per  lo  stream  (ferror)  e  viene  res4tuito  il  cara7ere  EOF.    

Leggo  caraHere  per  caraHere  

Leggo  riga  per  riga  

Soluzione  originale  

Soluzione  alterna4va  

Page 8: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

8 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1 Esercizi sull’uso dei file testuali (1°parte)

Soluzione  completa  …  /************************************************************************** * Nome: lab1-maiuscole.c * * Autore: Alessandro Saetti * * Data: 6/4/10 *

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

#define DIM 50 /* Nome: main * Scopo: Converte i caratteri da minuscolo a maiuscolo * Input: int argc: il numero di argomenti specificati da linea di comando

* char *argv: la linea di comando che contiene il nome del file da convertire * Output: 0 se il programma termina correttamente */

int main() { FILE *fp; char str[DIM];

int i; fp = fopen(" lab1.txt ", "r"); if (fp == NULL) {

printf("\nErrore apertura file!\n"); exit(0);

}

Page 9: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

9 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1 Esercizi sull’uso dei file testuali (1°parte)

…  soluzione  completa   while(feof(fp) == 0) { if (fgets(str, DIM, fp) != NULL) {

for (i =0 ; i < DIM && str[i] != '\0'; i++) if (str[i] >= 'a' && str[i] <= 'z')

printf("%c", str[i] - 'a' + 'A');

else printf("%c", str[i]);

} }

fclose(fp);

system("pause"); return 0; }

Page 10: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

10 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 Scrivere un programma C che visualizzi i 10 numeri interi contenuti nel file binario lab2.dat e successivamente sovrascriva il file invertendo l’ordine dei numeri.

Page 11: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

11 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 Esercizi sull’uso dei file testuali (1°parte)

/************************************************************************** * Nome: lab2-inverti.c * * Autore: Alessandro Saetti * * Data: 6/4/10 *

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

/* Nome: main * Scopo: Inverti gli interi binari presenti nel file "lab2.dat" * Input: - * Output: -

*/ int main() {

system("pause"); return 0; }

 Scrivere  un  programma  C  che  visualizzi  i  10  numeri  interi  contenu:  nel  file  binario  lab2.dat  e  successivamente  sovrascriva  il  file  invertendo  l’ordine  dei  numeri.  

Impos4amo  la  stru7ura  iniziale    del  nostro  programma  C  inserendo  eventuali  commen4  

//  ALGORITMO:  //  1)  Apro  il  file  “lab2.dat”  e  carico  i  numeri  in  memoria  //  2)  Riscrivo,  sempre  in  “lab2.dat”  l’elenco  dei  numeri  in  ordine  inverLto  

Page 12: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

12 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 Esercizi sull’uso dei file testuali (1°parte)

Nel  main()  

Inseriamo  nel  main()  il  codice  rela4vo  all’apertura  del  file  lab2.dat  e  alla  le7ura  dei  10  interi.  U4lizziamo  un’opportuna  #define  per  indicare  il  numero  massimo  di  valori  contenu4  in  tale  file.  

Aggiungiamo,  man  mano,  le  variabili  necessarie:  -­‐  la  variabile  v  conterrà  l’elenco  dei  numeri;    -­‐  il  puntatore  fp  alla  stru8ura  FILE  consen:rà    la  le8ura  e  la  riscri8ura  del  file  lab2.dat  -­‐  La  variabile  n  avrà  il  numero  di  valori  leQ  

#define DIM 10

Stampo  a  video  l’elenco  dei  10  numeri  appena  leQ  

Apro  il  file  binario  in  le8ura/scri8ura  (r+b)  e  control-­‐  lo  che  l’apertura  sia  avvenuta  corre8amente  (omesso  nella  slide  per  mancanza  di  spazio).  

Il  2^  argomento  di  fopen  indica  la  modalità  di  apertura

 Scrivere  un  programma  C  che  visualizzi  i  10  numeri  interi  contenuL  nel  file  binario  lab2.dat  e  successivamente  sovrascriva  il  file  invertendo  l’ordine  dei  numeri.  

printf(">> Sequenza di numeri originale:\n\t"); for (i = 0; i < n; i++) printf("%d ", v[i]); printf("\n");

int i; int v[DIM]; int n; FILE *fp;

fp = fopen("lab2.dat", "r+b");

La  funzione  fread()  legge  dallo  stream  fp  DIM  elemen4,  ciascuno  di  dimensione  sizeof(int).  Gli  elemen4  leQ  vengono  immagazzina4  nel  buffer  puntato  da  v  che  deve  essere  di  dimensioni  adeguate  (DIM*sizeof(int)).  La  funzione  fread()  res4tuisce  il  numero  n  di  elemen4  leQ.  In  caso  di  errore  o  di  raggiungimento  dell’ EOF  viene  res4tuito  un  numero  che  è  minore  di  DIM.  Conviene  chiamare  le  funzioni  feof()  e/o  ferror()  quando  il  valore  res4tuito  è  minore  di  DIM.  L'indicatore  di  posizione  dello  stream  viene  fa7o  avanzare  di  un  numero  di  byte  pari  a  quelli  leQ.    

Leggo  dieci  interi  e  li  carico  in  memoria  (array  v[])   n = fread(v, sizeof(int), DIM, fp);

Page 13: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

13 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 Esercizi sull’uso dei file testuali (1°parte)

Nel  main()  Aggiungiamo  nel  main()  il  codice  che  inverte  l’ordine  dei  valori  leQ  

Aggiungiamo  ulteriori  variabili  

 Scrivere  un  programma  C  che  visualizzi  i  10  numeri  interi  contenu:  nel  file  binario  lab2.dat  e  successivamente  sovrascriva  il  file  invertendo  l’ordine  dei  numeri.  

for (i = 0; i < n / 2; i++) { tmp = v[i]; v[i] = v[n - i - 1];

v[n - i - 1] = tmp; }

int tmp;

(i+1)-esima iterazione: (procedendo verso il centro della lista) si effettua lo swap tra l’i-esimo (v[i]) e il (n-1-i)-esimo elemento (v[n-1-i]). Termino quando l'elemento corrente a sinistra raggiunge l’elemento centrale (i>=n/2) dell’array v[]

Inver:amo  l’ordine  dei  valori  dire8amente    sull’array  v[]  

1^ iterazione: si effettua lo scambio (swap) tra il primo (v[0]) e l'ultimo elemento (v[n-1]) dell’array

Per invertire direttamente sull’arrey v[] senza utilizzare un ulteriore array posso utilizzare questo procedimento:

2^ iterazione: si effettua lo swap tra il secondo (v[1]) e il penultimo elemento (v[n-2]) dell’array

tmp = v[0]; v[0] = v[n - 1]; v[n - 1] = tmp;

tmp = v[1]; v[1] = v[n - 2]; v[n - 2] = tmp;

ooo

tmp = v[i]; v[i] = v[n–1-i]; v[n–1-i] = tmp;

Page 14: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

14 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 Esercizi sull’uso dei file testuali (1°parte)

Nel  main()  

Inseriamo  ora,  nel  main(),  il  codice  rela4vo  alla  scri7ura  su  file  dei  10  numeri  risistema4  in  ordine  inverso  

Ritorniamo  all’inizio  del  file  

 Scrivere  un  programma  C  che  visualizzi  i  10  numeri  interi  contenu:  nel  file  binario  lab2.dat  e  successivamente  sovrascriva  il  file  invertendo  l’ordine  dei  numeri.  

fwrite(v, sizeof(int), n, fp);

La  funzione  fwrite()  è  u4lizzata  per  la  scri7ura  di  file  binari.  Questa  funzione  scrive  sullo  stream  fp  n  elemen4,  ciascuno  di  dimensione  sizeof(int).  La  funzione  fwrite()  ritorna  il  numero  di  elemen4  scriQ.  In  caso  di  errore  viene  res4tuito  un  numero  minore  di  n.    E'  opportuno  chiamare  le  funzioni  feof()  e/o  ferror()  quando  la  funzione  res4tuisce  un  numero  minore  di  n.  L'indicatore  di  posizione  dello  stream  viene  fa7o  avanzare  di  un  numero  di  byte  pari  a  quelli  scriQ.  Il  totale  di  byte  scriQ  è  (n*sizeof(int)).  

...

Scriviamo  su  file,  in  un  sol  colpo,  l’intero  ve8ore  v[]  

fseek(fp, 0, SEEK_SET);

close(fp); Chiudo  il  flusso  fp.  

La  funzione  fseek(FILE  *fp,  long  int  offset,  int  dadove  )  imposta  l'indicatore  di  posizione  del  file.  La  prossima  operazione  di  I/O  su  stream  verra'  eseguita  sulla  nuova  posizione  appena  impostata  con  fseek().  La  posizione  e'  calcolata  aggiungendo  offset  (che  puo'  assumere  anche  valori  nega4vi)  byte  al  riferimento  dadove.  Il  parametro  dadove  puo'  valere:  -­‐ SEEK_SET:  per  indicare  l’inizio  del  file,    -­‐   SEEK_CUR:  per  specificare  la  posizione  corrente  dell’indicatore  di  posizione  (CURSORE),    -­‐   SEEK_END  per  specificare  la  fine  del  file.    In  caso  di  successo,  fseek()  ritorna  0  e  viene  eventualmente  cancellato  l'indicatore  di  fine  file.  In  caso  di  fallimento  ritorna  -­‐1.    

Page 15: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

15 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 Esercizi sull’uso dei file testuali (1°parte)

Come  soluzione  alterna4va,  invece  di  caricare  l’intera  sequenza  in  un  ve7ore,  si  poteva  procedere  con  l’inversione  dire7amente  nel  file.  Vediamo  come:  

for (i = 0; i < n / 2; i++) { tmp = v[i]; v[i] = v[n - i - 1]; v[n - i - 1] = tmp; }

SOLUZIONE  ALTERNATIVA  

Inversione  direHa  sul  file  

Inversione  in  memoria  (array)  

Inversione  dell’ordine  con  gli  array  (soluzione  originale)  

fseek(fp, i * sizeof(int), SEEK_SET); fread(&tmp, sizeof(int), 1, fp);

Mi  posiziono  sull’n-­‐i-­‐1  esimo  elemento  [rispe7o  alla  fine    del  file  la  posizione  (-­‐i-­‐1)*sizeof(int)]  e  lo  carico  in  tmp2  

fseek(fp,(-i-1)*sizeof(int), SEEK_END); fread(&tmp2, sizeof(int), 1, fp);

fseek(fp, -1 * sizeof(int), SEEK_CUR); fwrite(&tmp, sizeof(int), 1, fp);

fseek(fp, i * sizeof(int), SEEK_SET); fwrite(&tmp2, sizeof(int), 1, fp);

Mi  sposto  indietro  di  un  valore  [-­‐1*sizeof(int)  byte  rispet-­‐  to  alla  posizione  corrente].  Ritorno  quindi  sull’n-­‐i-­‐1  esimo  elemento  che  sovrascrivo  con  l’i-­‐esimo  valore  posto  in  tmp.  

Ecco  come  appare  byte  per  byte  (hex)  il  file  lab2.dat  -­‐  Si  osservi  l’occupazione  di  4  byte  di  ogni  valore  intero  –  Qui  i  valori  numerici  sono  mostratu  anche    in  base  esadecimale.  

Mi  posiziono  sull’i-­‐esimo  valore  [i*sizeof(int)  byte  dall’inizio  del  file].  Carico  in    tmp  l’i-­‐esimo  numero  

Ritorno  sull’ i-­‐esimo  elemento  [i*sizeof(int)  byte  dall’inizio]  e  sos:tuisco  il  valore  nel  file  con  il  contenuto  di  tmp2  che  corrisponde  al  valore  nella  n-­‐i-­‐1  esima  posizione  

for (i = 0; i < n / 2; i++) {

}

Inversione  dell’ordine  dire7amente  sul  file  (soluzione  alterna4va)  

Partendo  dai  2  valori  agli  estremi  del  file  procedo    verso  il  centro  [posizione  n/2]  del  file  in  questo  modo:    

Aggiungiamo  ulteriori  variabili   int tmp, tmp2;

Mi  sposto  di  un  valore  verso  l’interno  del  file  (i++).  

Contenuto  finale  del  file  LAB2.DAT  

Page 16: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

16 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 Esercizi sull’uso dei file testuali (1°parte) for (i = 0; i < n / 2; i++) {

fseek(fp, i * sizeof(int), SEEK_SET); // 1°STEP fread(&tmp, sizeof(int), 1, fp); fseek(fp, (-i-1) * sizeof(int), SEEK_END); // 2°STEP

fread(&tmp2, sizeof(int), 1, fp); fseek(fp, -1 * sizeof(int), SEEK_CUR); // 3°STEP

fwrite(&tmp, sizeof(int), 1, fp); fseek(fp, i * sizeof(int), SEEK_SET); // 4°STEP fwrite(&tmp2, sizeof(int), 1, fp);

}

(i+1)-esima iterazione: (procedendo verso il centro del file lista) si effettua lo swap tra l’i-esimo numero e l’ (n-i-1)-esimo. Termino quando raggiungo il centro del file (i>=n/2)

1^ iterazione (i=0): si effettua lo swap tra il primo elemento del file e l’ultimo fseek(fp,0*sizeof(int),SEEK_SET); fread(&tmp,sizeof(int),1,fp); fseek(fp,-1*sizeof(int),SEEK_END);

fread(&tmp2,sizeof(int),1,fp);

fseek(fp,-1*sizeof(int),SEEK_CUR); fwrite(&tmp,sizeof(int),1,fp);

fseek(fp,0*sizeof(int),SEEK_SET);

fwrite(&tmp2,sizeof(int),1,fp);

ooo

SOLUZIONE  ALTERNATIVA  Per  inver4re  dire7amente  l’elenco  dei  numeri  sul  file  si  è  usato  il  seguente  procedimento  

2^ iterazione (i=1): si effettua lo swap tra il secondo elemento del file e il penultimo

Contenuto  iniziale  del  file  LAB2.DAT  

fseek(fp,1*sizeof(int),SEEK_SET); fread(&tmp,sizeof(int),1,fp); fseek(fp,-2*sizeof(int),SEEK_END);

fread(&tmp2,sizeof(int),1,fp);

fseek(fp,-1*sizeof(int),SEEK_CUR); fwrite(&tmp,sizeof(int),1,fp);

fseek(fp,1*sizeof(int),SEEK_SET);

fwrite(&tmp2,sizeof(int),1,fp);

fseek(fp,i*sizeof(int),SEEK_SET); fread(&tmp,sizeof(int),1,fp); fseek(fp,(-i-1)*sizeof(int),SEEK_END);

fread(&tmp2,sizeof(int),1,fp);

fseek(fp,-1*sizeof(int),SEEK_CUR); fwrite(&tmp,sizeof(int),1,fp);

fseek(fp,i*sizeof(int),SEEK_SET);

fwrite(&tmp2,sizeof(int),1,fp);

Page 17: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

17 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 Esercizi sull’uso dei file binari (2°parte)

Soluzione  completa  …  /************************************************************************** * Nome: lab2-inverti.c * * Autore: Alessandro Saetti * * Data: 6/4/10 *

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

#define DIM 10 /* Nome: main * Scopo: Inverti gli interi binari presenti nel file "lab2.dat" * Input: -

* Output: - */ int main()

{ int v[DIM], i, n, tmp; FILE *fp;

// APERTURA E LETTURA FILE FILE *fp = fopen("lab2.bin", "r+b"); n = fread(v, sizeof(int), DIM, fp);

// OUTPUT: STAMPA SEQUENZA ORIGINALE printf(">> Sequenza di numeri originale:\n\t"); for (i = 0; i < n; i++)

printf("%d ", v[i]); printf("\n");

Page 18: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

18 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 Esercizi sull’uso dei file testuali (1°parte)

…  soluzione  completa   // RIORDINO IN MODO INVERTITO for (i = 0; i < n / 2; i++) { tmp = v[i];

v[i] = v[n - i - 1]; v[n - i - 1] = tmp; }

// VADO ALL’INIZIO DEL FILE E SCRIVO I NUMERI fseek(fp, 0, SEEK_SET); fwrite(v, sizeof(int), n, fp);

system("pause"); return 0;

}

Page 19: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

19 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizi sull’uso di file binari (+ funzioni e strutture dati)

3.  Scrivere una funzione C che, trattando con un nuovo tipo di dati “Prefisso” che aggrega due stringhe di 20 e 10 caratteri rappresentanti rispettivamente il nome ed il prefisso di un paese, svolga il seguente compito:

–  Visualizzi i nomi dei paesi contenuti in un dato file binario (contenente 13 prefissi telefonici). [Suggerimento: void stampa_tutto(FILE *fp);]

–  Visualizzi il prefisso telefonico contenuto in un dato file binario corrispondente ad un dato nome di paese. [Suggerimento: void stampa_prefisso(FILE *fp, char str[]);]

Scrivere inoltre un programma C che, sfruttando le funzioni precedentemente definite, visualizzi i nomi dei paesi contenuti nel file binario “prefissi.dat”, acquisisca da tastiera il nome di un paese ed infine visualizzi il corrispondente prefisso telefonico nel file.

Page 20: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

20 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3 Scrivere una funzione C che, trattando con un nuovo tipo di dati “Prefisso” che aggrega due stringhe di 20 e 10 caratteri rappresentanti rispettivamente il nome ed il prefisso di un paese, svolga il seguente compito: - Visualizzi i nomi dei paesi contenuti in un dato file binario (contenente 13 prefissi telefonici). [Suggerimento: void stampa_tutto(FILE *fp);] - Visualizzi il prefisso telefonico contenuto in un dato file binario corrispondente ad un dato nome di paese. [Suggerimento: void stampa_prefisso(FILE *fp, char str[]);] Scrivere inoltre un programma C che, sfruttando le funzioni precedentemente definite, visualizzi i nomi dei paesi contenuti nel file binario “prefissi.dat”, acquisisca da tastiera il nome di un paese ed infine visualizzi il corrispondente prefisso telefonico nel file.

Page 21: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

21 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3 Esercizi sull’uso dei file binari (2°parte)

/************************************************************ * Nome: lab3-stampaPrefissi.c * * Autore: Alessandro Saetti * * Data: 6/4/10 *

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

/* Nome: main * Scopo: Gestione dei prefissi telefonici internazionali

* Input: - * Output: 0 se il programma termina correttamente * 1 se il file che contiene i prefissi non esiste

*/ int main() {

system("pause"); return 0; }

 Scrivere  una  funzione  C  che,  traHando  con  un  nuovo  Lpo  di  daL  “Prefisso”  che  aggrega  due  stringhe  di  20  e  10  caraHeri  rappresentanL  rispe_vamente  il  nome  ed  il  prefisso  di  un  paese,  svolga  il  seguente  compito:    Visualizzi  i  nomi  dei  paesi  contenu:  in  un  dato  file  binario  (contenente  13  prefissi  telefonici).  [Suggerimento:  void  stampa_tu8o(FILE  *fp);]    Visualizzi  il  prefisso  telefonico  contenuto  in  un  dato  file  binario    corrispondente  ad  un  dato  nome  di  paese.    [Suggerimento:  void  stampa_prefisso(FILE  *fp,  char  str[]);]    Scrivere  inoltre  un  programma  C  che,  sfru8ando  le  funzioni  precedentemente  definite,  visualizzi  i  nomi  dei  paesi  contenu:  nel  file  binario  “prefissi.dat”,  acquisisca  da  tas:era  il  nome  di  un  paese  ed  infine  visualizzi  il  corrispondente  prefisso  telefonico  nel  file.  

Impos4amo  la  stru7ura  iniziale    del  nostro  programma  C  ed  inseriamo  la  stru7ura  da4  richiesta.  

//  Soluzione  richiesta  Definiamo  la  stru7ura  da4  più  ada7a  al  nostro  scopo  

#define DIM1 20 #define DIM2 10 typedef struct {

char paese[DIM1]; char prefisso[DIM2]; } Prefisso;

//  Definizione  struHure  daL  

Page 22: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

22 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3 Esercizi sull’uso dei file binari (2°parte)

#define DIM3 13 /* Nome: stampa_paesi * Scopo: Stampa il nome dei paese contenuti in un dato file binario

* Input: FILE *fp: il file da stampare * Output: - */ void stampa_paesi(FILE *fp) { Prefisso p[DIM3];

int i, n; n = fread(p, sizeof(Prefisso), DIM3, fp); for (i = 0; i < n; i++) printf("%12s\n", p[i].paese); }

 Scrivere  una  funzione  C  che,  tra8ando  con  un  nuovo  :po  di  da:  “Prefisso”  che  aggrega  due  stringhe  di  20  e  10  cara8eri  rappresentan:  rispeQvamente  il  nome  ed  il  prefisso  di  un  paese,  svolga  il  seguente  compito:    -­‐  Visualizzi  i  nomi  dei  paesi  contenuL  in  un  dato  file  binario  (contenente  13  prefissi  telefonici).  [Suggerimento:  void  stampa_paesi(FILE  *fp);]    -­‐  Visualizzi  il  prefisso  telefonico  contenuto  in  un  dato  file  binario    corrispondente  ad  un  dato  nome  di  paese.    [Suggerimento:  void  stampa_prefisso(FILE  *fp,  char  str[]);]    Scrivere  inoltre  un  programma  C  che,  sfru8ando  le  funzioni  precedentemente  definite,  visualizzi  i  nomi  dei  paesi  contenu:  nel  file  binario  “prefissi.dat”,  acquisisca  da  tas:era  il  nome  di  un  paese  ed  infine  visualizzi  il  corrispondente  prefisso  telefonico  nel  file.  

Stampo  il  campo  paese  di  ogni    elemento  dell’array  p[]  

Leggo  in  un  sol  colpo  le  13  stru8ure    contenen:  il  paese  e  il  prefisso    

abbinato  

Parametrizzo  il  numero  di    paesi  registra:  nel  file  

Definisco  il  buffer  che  conterrà  i  da:  registra:  nel  file  prefissi.dat  

La  funzione  stampa_paesi()  riceve  come  parametro  di  ingresso  il  puntatore  alla  stru7ura  FILE  associata  al  file  contenente  i  prefissi  (prefissi.dat).    

Page 23: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

23 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3 Esercizi sull’uso dei file binari (2°parte)

 Scrivere  una  funzione  C  che,  tra8ando  con  un  nuovo  :po  di  da:  “Prefisso”  che  aggrega  due  stringhe  di  20  e  10  cara8eri  rappresentan:  rispeQvamente  il  nome  ed  il  prefisso  di  un  paese,  svolga  il  seguente  compito:    -­‐  Visualizzi  i  nomi  dei  paesi  contenuL  in  un  dato  file  binario  (contenente  13  prefissi  telefonici).  [Suggerimento:  void  stampa_paesi(FILE  *fp);]    -­‐  Visualizzi  il  prefisso  telefonico  contenuto  in  un  dato  file  binario    corrispondente  ad  un  dato  nome  di  paese.    [Suggerimento:  void  stampa_prefisso(FILE  *fp,  char  str[]);]    Scrivere  inoltre  un  programma  C  che,  sfru8ando  le  funzioni  precedentemente  definite,  visualizzi  i  nomi  dei  paesi  contenu:  nel  file  binario  “prefissi.dat”,  acquisisca  da  tas:era  il  nome  di  un  paese  ed  infine  visualizzi  il  corrispondente  prefisso  telefonico  nel  file.  

Sfru7ando  la  funzione  fseek(),  Well()  e  sizeof()  è  possibile  calcolare  il  numero  n  di  record  presen4  nel  file.  

void stampa_paesi(FILE *fp) { Prefisso *p; int i, n;

// Determino la dimensione in byte del file fseek(fp, 0, SEEK_END); n = ftell(fp)/sizeof(Prefisso);

// Ritorno all'inizio del file fseek(fp, 0, SEEK_SET); p = (Prefisso *) calloc(n, sizeof(Prefisso)); fread(p, sizeof(Prefisso), n, fp);

for (i = 0; i < n; i++) printf("- %s\n", p[i].paese); }

Soluzione  alterna4va  

Stampa_paesi()  ALTERNATIVA  

La  funzione  Well()  res4tuisce  la  posizione  del  cursore  (indicatore  di  posizione)  del  file  passato  come  argomento  alla  funzione.  Tale  posizione  corrisponde  alla  distanza  in  byte  del  cursore  rispe7o  all'inizio  del  file  stesso.  La  funzione  può  essere  u4lizzata  per  calcolare  la  dimensione  in  byte  del  file  oppure  per  registrare  una  posizione  su  cui  occorre  ritornare  dopo  aver  eseguito  un’operazione  di  le7ura/scri7ura.  

Ecco  il  contenuto  del  file  prefissi.dat,  byte  per  byte,  con    evidenzia4    i  record  e  la  suddivisione  dei  campi  

Page 24: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

24 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3 Esercizi sull’uso dei file binari (2°parte)

void stampa_prefisso(FILE *fp, char str[]) { Prefisso p; fseek (fp, 0, SEEK_SET);

while(feof(fp) == 0) { fread(&p, sizeof(p), 1, fp);

if (strcmp(p.paese, str) == 0) { printf("Prefisso: %s\n", p.prefisso); return; }

} printf("\nErrore: paese non esistente!"); }

 Scrivere  una  funzione  C  che,  tra8ando  con  un  nuovo  :po  di  da:  “Prefisso”  che  aggrega  due  stringhe  di  20  e  10  cara8eri  rappresentan:  rispeQvamente  il  nome  ed  il  prefisso  di  un  paese,  svolga  il  seguente  compito:    -­‐  Visualizzi  i  nomi  dei  paesi  contenu:  in  un  dato  file  binario  (contenente  13  prefissi  telefonici).  [Suggerimento:  void  stampa_paesi(FILE  *fp);]    -­‐  Visualizzi  il  prefisso  telefonico  contenuto  in  un  dato  file  binario    corrispondente  ad  un  dato  nome  di  paese.    [Suggerimento:  void  stampa_prefisso(FILE  *fp,  char  str[]);]    Scrivere  inoltre  un  programma  C  che,  sfru8ando  le  funzioni  precedentemente  definite,  visualizzi  i  nomi  dei  paesi  contenu:  nel  file  binario  “prefissi.dat”,  acquisisca  da  tas:era  il  nome  di  un  paese  ed  infine  visualizzi  il  corrispondente  prefisso  telefonico  nel  file.  

La  funzione  stampa_prefisso()  riceve  come  parametri  il  nome  del  paese  str[]  del  quale  si  vuole  stampare  il  prefisso  e  il  puntatore  fp  alla  stru7ura  FILE  associata  al  file  da4  (prefissi.dat).    

/* Nome: stampa_prefisso * Scopo: Stampa il prefisso di un dato paese contenuto in un dato file binario * Input: FILE *fp: il file che contiene i prefissi * char str[]: nome del paese

* Output: - */

Definisco  il  buffer  p  che    conterrà  i  da:  associa:  ad  un  singolo  paese  

Finchè  non  sono  in  fondo  al  file  (feof(fp)==0)  leggo  i    

da:  di  un  paese  e  controllo  se  il  suo  nome  coincide    con  quello  ricercato  

Se  si  tra8a  del  paese      cercato,  indicato  in    

str[],    stampo  il  prefisso    e  termino  

Vado  all’inizio  del  file  

Leggo  una  stru8ura  alla  volta  

Page 25: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

25 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3 Esercizi sull’uso dei file binari (2°parte)

Nel  main()  

Aggiungiamo  nel  main()  il  codice  che  stampa  i  paesi  presen4  in  archivio,  richiede  il  nome  di  uno  stato  e  mostra,  se  esiste,  il  prefisso  associato.  

Inseriamo,  via  via,  la  dichiarazione  delle    variabili  necessarie  

Apro  il  file  Prefissi.dat  in  modalità  le8ura  binaria  e  controllo  che  non  vi  siano  errori  

 Scrivere  una  funzione  C  che,  tra8ando  con  un  nuovo  :po  di  da:  “Prefisso”  che  aggrega  due  stringhe  di  20  e  10  cara8eri  rappresentan:  rispeQvamente  il  nome  ed  il  prefisso  di  un  paese,  svolga  il  seguente  compito:    -­‐  Visualizzi  i  nomi  dei  paesi  contenu:  in  un  dato  file  binario  (contenente  13  prefissi  telefonici).  [Suggerimento:  void  stampa_paesi(FILE  *fp);]    -­‐  Visualizzi  il  prefisso  telefonico  contenuto  in  un  dato  file  binario    corrispondente  ad  un  dato  nome  di  paese.    [Suggerimento:  void  stampa_prefisso(FILE  *fp,  char  str[]);]    Scrivere  inoltre  un  programma  C  che,  sfru8ando  le  funzioni  precedentemente  definite,  visualizzi  i  nomi  dei  paesi  contenu:  nel  file  binario  “prefissi.dat”,  acquisisca  da  tas:era  il  nome  di  un  paese  ed  infine  visualizzi  il  corrispondente  prefisso  telefonico  nel  file.  

FILE *fp; char cerca[DIM1]; int x;

fp = fopen("prefissi.dat", "rb"); if (fp == NULL) { printf("\nErrore apertura file!\n"); exit(0);

}

printf("Stampa prefisso\nInserisci nome del paese: "); scanf("%s", cerca); stampa_prefisso(fp, cerca);

fclose(fp);

stampa_paesi(fp);

Al  termine  chiudo  il  file  

Stampo  i  nomi  di  tuQ  i  paesi  in  archivio  

Richiedo  il  nome  di  un  paese  e  lo  ricerco  u:lizzando    la  funzione  precedentemente  implementata  

Page 26: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

26 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3 Esercizi sull’uso dei file binari (2°parte)

Soluzione  completa  …  /************************************************************************** * Nome: lab3-stampaPrefissi.c * * Autore: Alessandro Saetti * * Data: 6/4/10 *

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

#define DIM1 20 #define DIM2 10 #define DIM3 15 typedef struct {

char paese[DIM1]; char prefisso[DIM2]; } Prefisso;

/* Nome: stampa_paesi * Scopo: Stampa il nome dei paese contenuti in un dato file binario * Input: FILE *fp: il file da stampare * Output: -

*/ void stampa_paesi(FILE *fp) { Prefisso p[DIM3];

int i, n; n = fread(p, sizeof(Prefisso), DIM3, fp); for (i = 0; i < n; i++)

printf("%12s\n", p[i].paese); }

Page 27: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

27 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3 Esercizi sull’uso dei file binari (2°parte)

…    soluzione  completa  …  /* Nome: stampa_prefisso * Scopo: Stampa il prefisso di un dato paese contenuto in un dato file binario * Input: FILE *fp: il file che contiene i prefissi * char str[]: nome del paese

* Output: - */ void stampa_prefisso(FILE *fp, char str[])

{ Prefisso p; fseek (fp, 0, SEEK_SET); while(feof(fp) == 0) {

fread(&p, sizeof(p), 1, fp); if (strcmp(p.paese, str) == 0) { printf("Prefisso: %s\n", p.prefisso);

return; } } printf("\nErrore: paese non esistente!");

} /* Nome: main * Scopo: Gestione dei prefissi telefonici internazionali

* Input: - * Output: 0 se il programma termina correttamente * 1 se il file che contiene i prefissi non esiste

*/

Page 28: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

28 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3 Esercizi sull’uso dei file testuali (1°parte)

…    soluzione  completa.  int main() { FILE *fp; char cerca[DIM1];

int x; // APERTURA FILE fp = fopen("prefissi.dat", "rb");

if (fp == NULL) { printf("\nErrore apertura file!\n"); exit(0); }

// STAMPA CONTENUTI stampa_paesi(fp); // RICERCA PREFISSO

printf("Stampa prefisso\nInserisci nome del paese: "); scanf("%s", cerca); stampa_prefisso(fp, cerca); // CHIUSURA FILE

fclose(fp); system("pause"); return 0;

}

Page 29: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

29 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizi sull’uso di file binari (+ funzioni e strutture dati)

4.  Scrivere una funzione C che, trattando con un nuovo tipo di dati “Prefisso” che aggrega due stringhe di 20 e 10 caratteri rappresentanti rispettivamente il nome ed il prefisso di un paese, svolga il seguente compito:

–  Aggiunga un dato prefisso telefonico ad un dato file binario. [Suggerimento: void aggiungi(FILE *fp, Prefisso p);]

Scrivere inoltre un programma C che, sfruttando le funzioni definite per l’esercizio 3 e la funzione precedentemente definita, acquisisca da tastiera il nome di un paese ed un prefisso telefonico, aggiunga questo dati al file binario “prefissi.dat”, acquisisca da tastiera il nome di un paese ed infine visualizzi il corrispondente prefisso telefonico nel file.

Page 30: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

30 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 4 Scrivere una funzione C che, trattando con un nuovo tipo di dati “Prefisso” che aggrega due stringhe di 20 e 10 caratteri rappresentanti rispettivamente il nome ed il prefisso di un paese, svolga il seguente compito:

–  Aggiunga un dato prefisso telefonico ad un dato file binario. [Suggerimento: void aggiungi(FILE *fp, Prefisso p);]

Scrivere inoltre un programma C che, sfruttando le funzioni definite per l’esercizio 3 e la funzione precedentemente definita, acquisisca da tastiera il nome di un paese ed un prefisso telefonico, aggiunga questo dati al file binario “prefissi.dat”, acquisisca da tastiera il nome di un paese ed infine visualizzi il corrispondente prefisso telefonico nel file.

Page 31: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

31 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 4 Esercizi sull’uso dei file binari (2°parte)

/************************************************************************** * Nome: lab4-aggiungiPrefisso.c * * Autore: Alessandro Saetti * * Data: 6/4/10 *

**************************************************************************/ #include <stdio.h>

#include <stdlib.h>

/* Nome: main * Scopo: Gestione dei prefissi telefonici internazionali

* Input: - * Output: 0 se il programma termina correttamente * 1 se il file che contiene i prefissi non esiste

*/ int main() {

system("pause"); return 0; }

Scrivere  una  funzione  C  che,  tra8ando  con  un  nuovo  Lpo  di  daL  “Prefisso”  che  aggrega  due  stringhe  di  20  e  10  caraHeri  rappresentanL  rispe_vamente  il  nome  ed  il  prefisso  di  un  paese,  svolga  il  seguente  compito:  

–   Aggiunga  un  dato  prefisso  telefonico  ad  un  dato  file  binario.  [Suggerimento:  void  aggiungi(FILE  *fp,  Prefisso  p);]  

Scrivere  inoltre  un  programma  C  che,  sfru8ando  le  funzioni  definite  per  l’esercizio  3  e  la  funzione  precedentemente  definita,  acquisisca  da  tas:era  il  nome  di  un  paese  ed  un  prefisso  telefonico,  aggiunga  questo  da:  al  file  binario  “prefissi.dat”,  acquisisca  da  tas:era  il  nome  di  un  paese  ed  infine  visualizzi  il  corrispondente  prefisso  telefonico  nel  file.  

//  Soluzione  richiesta  Riu4lizziamo  la  stru7ura  da4  del  precedente  esercizio  

#define DIM1 20 #define DIM2 10 typedef struct {

char paese[DIM1]; char prefisso[DIM2]; } Prefisso;

//  Definizione  struHure  daL  

Impos4amo  la  solita  stru7ura  iniziale    del  programma  C  e  riprendiamo  la  stru7ura  da4  implementata  nell’esercizio  precedente.  

Page 32: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

32 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 4 Esercizi sull’uso dei file binari (2°parte)

/************************************************************ * Nome: lab4-aggiungiPrefisso.c * * Autore: Alessandro Saetti * * Data: 6/4/10 *

************************************************************/ #include <stdio.h>

#include <stdlib.h>

int main() {

system("pause");

return 0; }

Scrivere  una  funzione  C  che,  tra8ando  con  un  nuovo  :po  di  da:  “Prefisso”  che  aggrega  due  stringhe  di  20  e  10  cara8eri  rappresentan:  rispeQvamente  il  nome  ed  il  prefisso  di  un  paese,  svolga  il  seguente  compito:  

–   Aggiunga  un  dato  prefisso  telefonico  ad  un  dato  file  binario.  [Suggerimento:  void  aggiungi(FILE  *fp,  Prefisso  p);]  

Scrivere  inoltre  un  programma  C  che,  sfruHando  le  funzioni  definite  per  l’esercizio  3  e  la  funzione  precedentemente  definita,  acquisisca  da  tas:era  il  nome  di  un  paese  ed  un  prefisso  telefonico,  aggiunga  questo  da:  al  file  binario  “prefissi.dat”,  acquisisca  da  tas:era  il  nome  di  un  paese  ed  infine  visualizzi  il  corrispondente  prefisso  telefonico  nel  file.  

//  Soluzione  richiesta  

//  stampa_prefisso();  

Riprendiamo  le  due  funzioni  definite  nell’esercizio  3  

void stampa_prefisso(FILE *fp, char str[]) { Prefisso p; fseek (fp, 0, SEEK_SET); while(feof(fp) == 0) { fread(&p, sizeof(p), 1, fp); if (strcmp(p.paese, str) == 0) { printf("Prefisso: %s\n", p.prefisso); return; } } printf("\nErrore: paese non esistente!"); }

//  stampa_paesi();  

#define DIM3 13 void stampa_paesi(FILE *fp) { Prefisso p[DIM3]; int i, n; n = fread(p, sizeof(Prefisso), DIM3, fp); for (i = 0; i < n; i++) printf("%12s\n", p[i].paese); }

Page 33: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

33 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 4 Esercizi sull’uso dei file binari (2°parte)

/* Nome: aggiungi * Scopo: Aggiungi il prefisso al file dei prefissi * Input: FILE *fp: il file che contiene i prefissi

* Output: - */ void aggiungi(FILE *fp, Prefisso p) { fseek(fp, 0, SEEK_END); fwrite(&p, sizeof(p), 1, fp);

}

Mi  posiziono  in  fondo  al  file  …  

…  e  registro  i  da:  del  nuovo  paese    passa:  alla  funzione  con  

l’argomento  p  

Definiamo  la  funzione  aggiungi()  che  riceve  come  parametri  i  da4  del  paese  (memorizza4  all’interno  della  variabile  p  di  4po  prefisso)  da  registrare  e  il  puntatore  fp  alla  stru7ura  FILE  associata  al  file  prefissi.dat.    

Scrivere  una  funzione  C  che,  tra8ando  con  un  nuovo  :po  di  da:  “Prefisso”  che  aggrega  due  stringhe  di  20  e  10  cara8eri  rappresentan:  rispeQvamente  il  nome  ed  il  prefisso  di  un  paese,  svolga  il  seguente  compito:  

–   Aggiunga  un  dato  prefisso  telefonico  ad  un  dato  file  binario.  [Suggerimento:  void  aggiungi(FILE  *fp,  Prefisso  p);]  

Scrivere  inoltre  un  programma  C  che,  sfru8ando  le  funzioni  definite  per  l’esercizio  3  e  la  funzione  precedentemente  definita,  acquisisca  da  tas:era  il  nome  di  un  paese  ed  un  prefisso  telefonico,  aggiunga  questo  da:  al  file  binario  “prefissi.dat”,  acquisisca  da  tas:era  il  nome  di  un  paese  ed  infine  visualizzi  il  corrispondente  prefisso  telefonico  nel  file.  

Page 34: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

34 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 4 Esercizi sull’uso dei file binari (2°parte)

Nel  main()  Riprendiamo  il  main()  dell’esercizio  3  e  inseriamo  le  opportune  modifiche  Riu:lizziamo  le  variabili  dell’esercizio  3  ed    aggiungiamo  quella  necessaria  a  memorizzare  i  da:  del  nuovo  paese.    

Apriamo  il  file  Prefissi.dat  sia  in  le8ura  che  scri8ura  (r+b)  [si  deve  aggiungere  dei  da4!]  e  controlliamo    eventuali  errori.  

FILE *fp; char cerca[DIM1]; int x; Prefisso p;

fp = fopen("prefissi.dat", "r+b"); if (fp == NULL) { printf("\nErrore apertura file!\n"); exit(0);

}

stampa_paesi(fp); printf("Stampa prefisso\nInserisci nome del paese: "); scanf("%s", cerca); stampa_prefisso(fp, cerca);

Fclose(fp);

Riprendendiamo  le  stesse  istruzioni  dell’esercizio  3    rela:ve  a:  -­‐    stampa  dell’elenco  dei  paesi,  -­‐     richiesta  di  un  nome  di  un  paese    -­‐     visualizzazione  del  prefisso  associato  a  tale  paese.  

Richiediamo  i  da:  del  nuovo  paese  che  poi  aggiun-­‐    giamo  al  file  mediante  la  funzione  precedentemente    implementata:  aggiungi().  

Scrivere  una  funzione  C  che,  tra8ando  con  un  nuovo  :po  di  da:  “Prefisso”  che  aggrega  due  stringhe  di  20  e  10  cara8eri  rappresentan:  rispeQvamente  il  nome  ed  il  prefisso  di  un  paese,  svolga  il  seguente  compito:  

–   Aggiunga  un  dato  prefisso  telefonico  ad  un  dato  file  binario.  [Suggerimento:  void  aggiungi(FILE  *fp,  Prefisso  p);]  

Scrivere  inoltre  un  programma  C  che,  sfru8ando  le  funzioni  definite  per  l’esercizio  3  e  la  funzione  precedentemente  definita,  acquisisca  da  tasLera  il  nome  di  un  paese  ed  un  prefisso  telefonico,  aggiunga  questo  daL  al  file  binario  “prefissi.dat”,  acquisisca  da  tasLera  il  nome  di  un  paese  ed  infine  visualizzi  il  corrispondente  prefisso  telefonico  nel  file.  

printf("Aggiungi prefisso\nInserisci paese: "); scanf("%s", p.paese); printf("Inserisci prefisso: "); scanf("%s", p.prefisso);

aggiungi(fp, p);

Page 35: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

35 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 4 Esercizi sull’uso dei file binari (2°parte)

Soluzione  completa  …  /************************************************************************** * Nome: lab4-aggiungiPrefisso.c * * Autore: Alessandro Saetti * * Data: 6/4/10 *

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

#define DIM1 20 #define DIM2 10 #define DIM3 30

typedef struct { char paese[DIM1]; char prefisso[DIM2];

} Prefisso; /* Nome: aggiungi * Scopo: Aggiungi il prefisso al file dei prefissi

* Input: FILE *fp: il file che contiene i prefissi * Output: - */ void aggiungi(FILE *fp, Prefisso p)

{ fseek(fp, 0, SEEK_END); fwrite(&p, sizeof(p), 1, fp);

}

Page 36: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

36 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 4 Esercizi sull’uso dei file binari (2°parte)

…  soluzione  completa  …  

/* Nome: stampa_paesi * Scopo: Stampa il nome dei paese contenuti in un dato file binario * Input: FILE *fp: il file da stampare * Output: - */

void stampa_paesi(FILE *fp) { Prefisso p[DIM3]; int i, n;

fseek(fp, 0, SEEK_SET); n = fread(p, sizeof(Prefisso), DIM3, fp); for (i = 0; i < n; i++) printf("%12s\n", p[i].paese); }

/* Nome: stampa_prefisso * Scopo: Stampa il prefisso di un dato paese contenuto in un dato file binario * Input: FILE *fp: il file che contiene i prefissi - char str[]: nome del paese

* * Output: - */ void stampa_prefisso(FILE *fp, char str[]) { Prefisso p; fseek (fp, 0, SEEK_SET);

while(feof(fp) == 0) { fread(&p, sizeof(p), 1, fp); if (strcmp(p.paese, str) == 0) { printf("Prefisso: %s\n", p.prefisso);

return; } }

printf("Errore: paese non esistente!"); }

Page 37: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

37 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 4 Esercizi sull’uso dei file binari (2°parte)

…  soluzione  completa  

/* Nome: main * Scopo: Gestione dei prefissi telefonici internazionali * Input: - * Output: 0 se il programma termina correttamente

* 1 se il file che contiene i prefissi non esiste */ int main() {

FILE *fp = fopen("prefissi.dat", "r+b"); char cerca[DIM1]; int x; Prefisso p;

if (fp == NULL) { printf("\nErrore apertura file!\n"); exit(0);

} printf("Aggiungi prefisso\nInserisci paese: "); scanf("%s", p.paese); printf("Inserisci prefisso: ");

scanf("%s", p.prefisso); aggiungi(fp, p); stampa_paesi(fp); printf("Stampa prefisso\nInserisci nome del paese: ");

scanf("%s", cerca); stampa_prefisso(fp, cerca); fclose(fp);

system("pause"); return 0; }

Page 38: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

38 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizi sull’uso di file testuali (per casa)

1.  Scrivere un programma C che visualizzi (in sequenza) il contenuto di un numero qualsiasi di file di testo, i cui nomi sono definiti dalla riga di comando.

2.  Scrivere un programma C che, dato il nome di un file testuale ed una parola specificati tramite la linea di comando, stampi a video le righe del file in cui compare tale parola.

3.  Scrivere un programma C che, dato il nome di un file di testo definito dalla linea di comando, visualizzi il numero di caratteri, il numero di parole (una parola è una qualsiasi sequenza di caratteri delimitata da uno spazio bianco o un carattere di file linea) ed il numero di righe contenute nel file.

Page 39: Fondamenti di Programmazione - Corsi di Informatica...Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia A.A. 2013/2014 2 Esercizi sull’uso di file

39 A.A. 2013/2014 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizi sull’uso di file binari + funzioni e strutture dati (per casa) 4.  Scrivere una funzione C che, trattando con un nuovo tipo

di dati “Prefisso” che aggrega due stringhe di 20 e 10 caratteri rappresentanti rispettivamente il nome ed il prefisso di un paese, svolga il seguente compito:

–  Scriva i prefissi telefonici contenuti in un dato file binario in un secondo dato file testuale. [Suggerimento: void esporta(FILE *fp, FILE *fp_dest);]

Scrivere un programma C che, sfruttando la funzione precedentemente definita, copi il contenuto del file binario “Prefissi.dat” in un file testuale il cui nome è specificato dalla linea di comando.