Un file binario è un flusso di byte, una sequenza di unità d'informazione non
interpretate, che quindi possono rappresentare qualunque informazione (testi, numeri, immagini...).
Nel file stdio.h sono dichiarate in particolare le function:
fopen() Apre il file
fclose() Chiude il file
fread() Legge dal file
fwrite() Scrive sul file
fgetc() Legge il prossimo byte del file
fputc() Scrive un carattere nel file
fseek() Scorre lungo il file
ftell() restituisce la posizione attuale nel file
Tra queste, per aprire il file che ha nome nomefile da associare a un flusso di dati,
FILE *fopen(char *nomefile, char *mode);
in cui la stringa mode può avere i seguenti valori:
"rb" Apre un file binario per la lettura
"wb" Crea un file binario per la scrittura
"ab" Appende a un file binario
"r+b" Apre un file binario per la lettura/scrittura
"w+b" Crea un file binario per la lettura/scrittura
"a+b" Apre o crea un file binario per la lettura/scrittura
Su un file è possibile scrivere informazione mediante:
int fwrite(nomevariabile, int dimensione, int numero elementi, FILE *nomefile);
per scrivere dal file un certo numero di elementi di dimensione dichiarata in byte a partire dall'indirizzo della variabile indicata. Restituisce il numero di elementi (non di byte) effettivamente
scritti, eventualmente meno di n se il file finisce prima.
Importante è anche la chiusura del file con:
FILE *fclose(char *nomefile);
Redigere ed eseguire il programma seguente per creare eventualmente e aprire un file binario e scrivervi un vettore di 10 numeri interi
#include <stdio.h>
main(){
FILE *fp; // Dichiara una variabile del tipo flusso d'informazione
fp = fopen ("a:numeri.dat", "wb"); // Associa a tale flusso un file su disco
if (fp == NULL){
printf ("errore di apertura \n");
}else{
int vet[13] = {1,2,3,4,5,6,7,8,9,10,11,12,13};
fwrite (vet, sizeof(int), 13, fp);
fclose(fp);
}
}
Visualizzare l'elenco dei file presenti sul disk A: controllando che tra questi compaia numeri.dat
Aprire con il Blocco note il file numeri.dat ([Tasto destro del mouse]Nuovo|Documento di testo e trascinare sul foglio vuoto l'icona di numeri.dat) verificandone l'illegibilità
Redigere ed eseguire il programma seguente per leggere il file binario numeri.dat mediante la function
int fread(&nomevariabile, int dimensione, int numero elementi, FILE *nomefile);
per leggere dal file un certo numero di elementi di dimensione dichiarata in byte componenti la variabile della quale viene indicato l'indirizzo. Restituisce il numero di elementi (non di byte) effettivamente
letti, eventualmente meno di n se il file finisce prima.
#include <stdio.h>
main(){
FILE *fp;
fp = fopen ("a:numeri.dat", "rb");
if (fp == NULL){
printf ("errore di apertura \n");
}else{
int vett[100];
int i=0;
while(fread(&vett[i],sizeof(int),1,fp)>0){
printf("%d\n",vett[i]);
}
fclose(fp);
}
}
Modificare i precedenti programmi in modo che il file dei dati si riferisca a tipi float
Modificare i precedenti programmi in modo che si debba dichiarare il tipo di dato
Realizzare un programma che proponga un menu: crea, leggi, cancella, aggiungi dati (da inserire da tastiera)
File testo
I file binari sono sufficienti a qualunque scopo. Tuttavia, per la gestione di sequenze di
caratteri, viene offerta una grande comodità, quella dei file di testo. Infatti nei file di testo
esiste un concetto di riga e di fine riga (‘\n’)
certi caratteri sono stampabili a video
la sequenza di caratteri è chiusa dal carattere speciale EOF (Per generare EOF sulle piattaforme
PC basta combinare i tasti [Ctrl]+Z).
L'apertura e la chiusura dei file si fanno come già visto, cambia solo per l'apertura la stringa mode,
che in questo caso può avere i valori:
"r" Apre un file testo per la lettura
"w" Crea un file testo per la scrittura
"a" Appende a un file testo
"r+" Apre un file testo per la lettura/scrittura
"w+" Crea un file testo per la lettura/scrittura
"a+" Apre o crea un file testo per la lettura/scrittura
"rt" Apre un file testo per la lettura
"wt" Crea un file testo per la scrittura
"at" Appende a un file testo
"r+t" Apre un file testo per la lettura/scrittura
"w+t" Crea un file testo per la lettura/scrittura
"a+t" Apre o crea un file testo per la lettura/scrittura
I canali di I/O standard non sono altro che file di testo già aperti:
stdin è un file di testo aperto in lettura, di norma agganciato alla tastiera;
stdout è un file di testo aperto in scrittura, di norma agganciato al video;
stderr è un altro file di testo aperto in scrittura, di norma agganciato al video.
Le funzioni di I/O disponibili per i file di testo sono una generalizzazione di quelle già
note per i canali di I/O standard.
Nel file stdio.h sono dichiarate in particolare le function:
da console da file
int getchar(void); int fgetc(FILE* f);
int putchar(int c); int fputc(int c, FILE* f);
char* gets(char* s); char* fgets(char* s, int n, FILE* f);
int puts(char* s); int fputs(char* s, FILE* f);
int printf( ... ); int fprintf(FILE* f, ... );
int scanf( ... ); int fscanf(FILE* f, ... );
Redigere ed eseguire il seguente programma per salvare su un file di testo ciò che viene battuto sulla tastiera (utilizzare la combinazione di tasti [Ctrl]+Z per terminare l'immissione dei dati).
#include <stdio.h>
main(){
FILE *fp;
fp = fopen ("a:testo.txt", "wt");
char car;
if (fp != NULL){
car=getchar();
while (car!=EOF){
fputc(car, fp);
car=getchar();
}
fclose(fp);
}else{
printf ("errore di apertura del file in scrittura");
}
}
Visualizzare l'elenco dei file presenti sul disk A: controllando che tra questi compaia testo.txt
Leggere il contenuto di testo.txt
Modificare tale file testo con gli strumenti di editoria del Blocco note
Redigere ed eseguire il seguente programma per stampare a video il contenuto di un file testo
#include <stdio.h>
main(){
FILE *fp;
int car;
fp = fopen ("a:testo.txt", "rt");
if (fp != NULL){
do{
car=fgetc(fp);
putchar(car);
}while (car!=EOF);
fclose(fp);
}else{
printf ("errore di apertura del file in lettura");
}
}
Scorrere un file, ovvero riposizionare il 'file pointer' in uno stream, mediante la function
int fseek(FILE *nomefile, long numero, int opzione);
la nuova posizione è un certo numero di byte dalla collocazione iniziale fissata dall'opzione tra le seguenti possibili:
che restituisce il valore 0 se l'azione ha successo, un valore non nullo atrimenti.
#include <stdio.h>
main(){
FILE *fp;
char car;
fp = fopen ("a:testo.txt", "r+");
if (fp != NULL){
do
car=fgetc(fp);
while (car!='a');
fseek(fp,-1,SEEK_CUR);
fputc('X',fp);
fclose(fp);
}else{
printf ("errore di apertura del file in lettura/scrittura");
}
}
Modificare il precedente programma in modo da sostituire tutte le occorrenze di una dato carattere con un altro carattere dato.
Per ottenere la posizione raggiunta all'interno del file, il file pointer corrente,
si può usare la function:
long int ftell(FILE *stream);
Tale posizione è il n° di bytes dall'inizio del file oppure -1L in caso di errore.
Redigere ed eseguire il seguente programma che restituisce la lunghezza, in byte, di un file
#include <stdio.h>
main(){
FILE *fp;
fp = fopen ("a:testo.txt", "rt");
if (fp != NULL){
fseek(fp,0L,SEEK_END);
printf ("numero di caratteri del file: %ld",ftell(fp));
fclose(fp);
}else{
printf ("errore di apertura del file in lettura");
}
}
Modificare il programma per la lettura di un file di testo in modo da richiedere in input il nome del file.
Realizzare un programma che verifichi se una certa parola è contenuta in un
file di testo.
Strutture
Oltre ai tipi di dato semplici, predefiniti come int, char, float, double, ... ( ma anche definibili dall'utente
con il costruttore 'enum') vi sono altri tipi di dato, strutturati come quelli che si ottengono
mediante il costruttore [] (array), definiti con il costruttore struct.
struct nomeStruttura {
definizione di componente ;
definizione di componente ;
..........
definizione di componente ;
};
Ad esempio per definire la struttura:
struct persona {
char cognome[20];
char nome[20];
char sesso:
int anno;
};
oppure per definire un identificatore di tipo di dato strutturato:
Scrivere un programma che cerchi nell'archivio se vi sono persone con un dato cognome
A differenza di quanto accade con gli array, il nome della struttura rappresenta la struttura
nel suo complesso. Quindi si possono fare assegnazioni tra strutture o realizzare function che hanno per valore una struttura;
si può inoltre passare una struttura come parametro a una funzione (passaggio per valore).
Completare il programma seguente per le trasformazioni nel piano.
#include <stdio.h>
typedef struct {float x, y;} punto; // di coordinate (x;y)
typedef struct {float a, b, c;} retta; // di equazione ax+by+c=0
punto traslaz(punto, punto);
punto simm(punto,punto);
punto simmAss(punto,retta);
punto rotaz(punto,punto,float);
punto leggiPto();
retta leggiRetta();
main(){
punto P=leggiPto();
unsigned int op;
printf("\nTrasformazioni:\n1: traslazione;2\n simmetria centrale;");
printf("\n3 simmetria assiale:\n4: rotazione;\n\n scelta ?");
scanf("%d",&op);
switch (op){
case1 :
printf ("Corrispondente di O(0,0) nella traslazione ?");
punto T=leggiPto();
P=traslaz(P,T);
break;
case2 :
printf ("Centro di simmetria ?");
punto S=leggiPto();
P=simm(P,S);
break;
case3 :
printf ("Asse di simmetria ?");
retta asse;
asse=leggiRetta();
P=simmAss(P,asse);
break;
case4 :
printf ("Centro di rotazione ?");
punto C=leggiPto();
printf ("\nAngolo di rotazione (rad)?");
float ang;
scanf("%f",&ang);
P=rotaz(P,C,ang);
break;
}
printf("\n\nLe nuove coordinate sono x = %f e y = %f",P.x,P.y);
}
punto leggiPto(){
punto P;
printf ("x = "); scanf("%f",&P.x);
printf ("y = "); scanf("%f",&P.y);
return P;
}
punto traslaz(punto P, punto T){
punto P1;
P1.x = P.x + T.x;
P1.y = P.y + T.y;
return P1;
}
punto simm(punto P, punto S){
punto P1;
P1.x = 2*S.x - P.x;
P1.y = 2*S.y - P.y;
return P1;
}
pagine di Roberto Ricci
L.S. "A. Righi", Bologna.
Ultima revisione