Fondamenti di Informatica
Il Linguaggio C:
Le basi
Monica Mordonini
Dipartimento di Ingegneria dell’Informazione Università degli Studi di Parma
Le funzioni di input/output
<stdio.h>
Input / Output
4Il linguaggio C consente di definire funzioni aggiuntive raggruppabili eventualmente in librerie.
4Esiste in particolare una libreria standard (standard library) di funzioni; per rendere disponibili tali funzioni, occorre inserire nelle dichiarazioni globali del programma, la direttiva di precompilazione:
#include <stdio.h>
4La libreria standard comprende, tra le altre, le seguenti funzioni di input/output
Input / Output
printf (<stringa di formato >[,<lista di espressioni>])
4per visualizzare dati sullo standard output
4<lista di espressioni> ::= <espressione> {,<espressione>}
–sono espressioni il cui valore deve essere visualizzato 4<stringa di formato>: contiene caratteri da visualizzare ed i
simboli di formato per i valori delle espressioni da visualizzare:
–%d per la visualizzazione di un numero intero –%f per la visualizzazione di un numero reale –%c per la visualizzazione di un carattere –%s per la visualizzazione di una stringa
Esempi
printf (“Questa è una frase di
prova\n”);
printf (“La somma di %d e %d risulta:
%d\n”, m, n, m+n);
printf (“Il codice ASCII %d\nviene
visualizzato come %c\n”,61,61)
–Il codice ASCII 61viene visualizzato come A
Input / Output
scanf (<stringa di formato >,<lista indirizzi variabili>)
4consente la lettura di dati dallo standard input
4<lista di indirizzi di variabili> ::= <indirizzo> {,<indirizzo>}
<indirizzo> ::= &<variabile>
4<stringa di formato>
4Esempio scanf (“%d %f %c”, &n, &x, &c);
scanf (“%s”, nomestringa);
Ma ã
Esempio
4Programma che legge due numeri e ne visualizza la somma
#include <stdio.h>
int main(){
int m, n;
printf (“Inserire primo numero:”);
scanf (“%d”, &m);
printf (“Inserire secondo numero:”);
scanf (“%d”, &n);
printf (“La somma di %d e %d risulta
%d\n”, m, n, m+n);
return 0;
}
Esempio
4Legge un codice ASCII e ne visualizza il carattere
#include <stdio.h>
int main(){
char c;
printf (“Inserire il codice ASCII:”);
scanf (“%d”, &c);
printf (“Il carattere corr. è %c\n”, c);
return 0;
}
Strutture di controllo
If, while, for, ...
Strutture di controllo
4
Selezione if
if (<condizione>) <istruzioni> [else <istruzioni>]
<istruzioni> ::= <istruzione> | ‘{‘ <istruzione> {<istruzione>} ’}’
A esempio if (x > 0)
y = x;
else y = -x;
printf(“dato %d\n”, y);
operatori di confronto maggiore >
maggiore o uguale >=
minore <
minore o uguale <=
uguale ==
diverso !=
falso ↔0 vero ↔non 0
operatori logici not!
and&&
or| |
Esempio
/* Dati due numeri in ingresso, individua il maggiore*/
#include <stdio.h>
#include <conio.h>
int main(){
int num1,num2;
clrscr()
printf("Immetti i due numeri:");
scanf("%d%d",&num1,&num2);
if (num1==num2) printf("I due numeri sono uguali");
else
if(num1>num2)printf("Il primo è maggiore”);
else printf("Il secondo è maggiore");
return 0;
}
Strutture di controllo
4Ciclo for
for(<istr.iniziale>;<condizione>;<istr. ciclica>)<istr.>
Aesempio: calcolo della somma dei primi 100 numeri naturali
#include <stdio.h>
int main(){
int i, somma= 0;
for ( i=1; i<=100; i=i+1) somma= somma+i;
printf (“La somma vale: %d\n”, somma);
return 0;
}
Strutture di controllo
4Ciclo while
while (<condizione>) <istruzioni>
A esempio: calcolo radice quadrata intera (cioè la parte intera) di un numero intero n
#include <stdio.h>
int main(){
int n, radice= 1;
printf (“Inserire il numero:”);
scanf (“%d”, &n);
while (radice*radice<= n) radice++;
radice−−;
printf (“La radice vale %d\n”, radice);
return 0;}
radice=radice−1 può essere scritto radice− −
oppure
− −radice
Operatori di incremento e decremento
4 ++ e -- 4 Esempi
– y=x++
il contenuto della variabile x viene inizialmente usata per l’assegnazione y, e solo dopo incrementata
– y=--x
il contenuto della variabile x viene inizialmente incrementato di uno e solo dopo viene effettuata l’assegnazione di x a y
Strutture di controllo
4Ciclo do
do <istruzioni> while (<condizione>)
Esempio trovare un programma che legge e addiziona dei numeri, termina quando la somma supera il valore 1000
#include <stdio.h>
int main(){
int i, somma=0, cont =0;
do{
printf (“Inserire nuovo numero:”);
scanf (“%d”, &i);
somma = somma + i;
cont++;
}while (somma<= 1000);
printf (“I numeri letti sono %d\n”,cont);
return 0;
}
Strutture di controllo
4Selezione switch
<istr. switch>::=switch(<espr.>)‘{‘<istr. case>|<istr. default>’}’
<istr.case>::=case<valore intero>:{case <valore intero>:} <istr.> [break]
<istr. default>::=default <istr.>
2 A Legge due numeri ed un simbolo di operazione (+,−,∗,/); visualizza il risultato dell’operazione richiesta
#include <stdio.h>
int main(){
int m,n;
char operazione,invio;
printf (“Inserire i due numeri:”);
scanf (“%d%d”, &m,&n);
printf (“Inserire l’operazione:”);
scanf (“%c%c”, &invio, &operazione);
Strutture di controllo
switch (operazione) { case ‘+’:
printf(“Risultato %d\n”, m+n);
break;
case ‘−’:
printf(“Risultato %d\n”, m−n);
break;
case ‘∗’:
printf(“Risultato %d\n”, m∗n);
break;
case ‘/’:
printf(“Risultato %d\n”, m/n);
break;
default:
printf(“operazione non consentita\n”);
} return 0;}
Esempio
/* Legge la data di nascita di una persona nel formato giorno/mese/anno e la data attuale nello stesso formato; calcola poi l'età della persona in anni */
#include <stdio.h>
int main(){
int g_att,m_att,a_att,g_nas,m_nas,a_nas;
printf("immetti la data di nascità: ");
scanf("%d%d%d",&g_nas,&m_nas,&a_nas);
printf("immetti la data attuale: ");
scanf("%d%d%d",&g_att,&m_att,&a_att);
if (m_att>m_nas || m_att==m_nas && g_att>=g_nas) printf("l'età (in anni) è : %d",a_att-a_nas);
else
printf("l'età (in anni) è : %d",a_att-a_nas-1);
return 0;
}
Strutture dati
Vettori e matrici
Strutture di dati
Una struttura di dati ha le seguenti proprietà:
4è un insieme di dati
– Es. una struttura contenente il totale delle vendite effettuate da un’azienda in ognuno dei dodici mesi di un anno
4ogni dato dell’insieme può essere singolarmente identificato rispetto agli altri
– Es. si deve poter conoscere il totale venduto in un certo mese 4la modalità di identificazione dei singoli dati, consente che una stessa
istruzione, eseguita in momenti diversi, possa operare su diversi dati della struttura
– Es. deve essere possibile leggere, con un ciclo, tutte le fatture (emesse da un’azienda, contenute in un archivio)
4possono esistere operazioni che agiscono a livello dell’intera struttura
Vettori
4un vettore (array unidimensionale) è un insieme di elementi dello stesso tipo
4ha un nome che lo identifica
4gli elementi del vettore vengono identificati, oltre che con il nome del vettore di appartenenza, con il valore di un indice numerico
31 28 31 0 1 2
giorni_mese
nome vettore
indice contenuto
Vettori
4per identificare un elemento si utilizza il nome del vettore seguito dal valore dell’indice racchiuso tra parentesi.
es. giorni_mese [3]
4il valore dell’indice può essere una qualsiasi espressione; ad esempio es. giorni_mese [n+3]
4occorre dichiarare il tipo degli elementi e la dimensione del vettore (in C i vettori hanno dimensione prefissata)
<tipo> <nome> ‘[‘ <dimensione> ‘]’
4il valore dell’indice parte da zero
4un vettore occupa locazioni contigue di memoria
4il C non effettua alcun controllo (né in fase di compilazione, né in fase di esecuzione) sul superamento dei limiti di un vettore
Vettori
/* Programma che legge n numeri in un vettore e li visualizza in ordine inverso */
#include <stdio.h>
#define MAX 100 int main (){
int n, i, numeri[MAX ];
/* Lettura dimensione vettore */
printf (“Inserire il numero di elementi:”);
scanf (“%d”, &n);
if (n>MAX) printf (“Valore troppo elevato\n”);
else{
/* lettura dei numeri */
for (i=0; i<n; i++){
printf (“Inserire un numero:”);
scanf (“%d”, &numeri[i]);
}
/* visualizzazione dei numeri in ordine inverso */
for(i=n−1; i>=0; i−−) printf (“%d\n”, numeri[i]);
} return 0;}
Array Multidimensionale
4
hanno due o più indici (o dimensioni)
4
in C, occorre dichiarare la dimensione di ogni indice
<tipo> <nome> ‘[‘<dimensione>‘]’ {
‘[‘<dimensione>‘]’ }
4
i vettori bidimensionali sono denominati matrici
Esempio
/*legge, per righe, gli elementi di una matrice 2×3 e stampa la somma di ogni riga*/
#include <stdio.h>
#define N_RIGHE 2
#define N_COLONNE 3 int main(){
int i, j, somma, numeri[N_RIGHE][N_COLONNE];
for (i=0; i<N_RIGHE; i++) { printf (“Inserisci riga n.%d\n”, i+1);
for (j=0; j<N_COLONNE; j++) {
printf (“Inserisci elemento n.%d:”, j+1);
scanf (“%d”, &numeri[i][j]);
} }
for (i=0; i<N_RIGHE; i++) { somma=0;
for (j=0; j<N_COLONNE; j++) somma+=numeri[i][j];
printf (“La somma della riga n.%d vale %d\n”, i+1, somma);
} return 0;}
Caratteri e stringhe
<string.h>
Caratteri e Stringhe
4Lettura di un carattere da tastiera (dispositivo standard di input):
getchar()
accetta caratteri fino alla pressione del tasto invio;
solo allora restituisce il primo carattere inserito; gli altri restano in memoria.
4Scrittura di un carattere sullo schermo (dispositivo standard di output)
putchar (<espressione carattere>)
Caratteri e stringhe
4 Esempi char c;
c=getchar();
putchar(c)
Stringa
4È una sequenza di caratteri
4In C non esiste il dato di tipo stringa; una stringa viene memorizzata in un array di caratteri
char nome[30]
4Il C usa la tecnica di contrassegnare la fine effettiva di una stringa con il carattere avente codice 0 ( ‘\0’)
4Inizializzazione di una stringa:
char nome[30]=”Luca” (inserisce automaticamente il carattere ‘\0’)
Lettura di una stringa da tastiera
gets (<array>) //termina l’immissione con il tasto
“invio”
scanf (“%s”, <array>) //termina l’immissione con il tasto “invio” (il codice del tasto invio non viene letto) 4
in entrambi i casi, l’inserimento di un numero di
caratteri maggiore della lunghezza dell’array, ha
effetti imprevedibili
Scrittura di una stringa su schermo
puts(<espressione stringa>) //aggiunge
‘\n’
printf (“%s”, <espressione stringa>) Es. puts (stringa);
printf (“%s %s\n”, stri1, stri2);
Esempio
//legge una stringa e conta le eventuali cifre presenti al suo interno
#include <stdio.h>
#define MAX_CAR 128 int main() {
int i, n_cifre=0;
char stringa [MAX_CAR];
puts (“Inserire una stringa:”);
gets (stringa);
for (i=0; i<MAX_CAR; i++) { if (stringa[i]==’\0’) break;
if (stringa[i]>=’0’ && stringa[i]< =’9’) n_cifre++;
}
printf (“Il numero di cifre è %d\n”, n_cifre);
return 0;
}
Funzioni di manipolazione delle stringhe
4Per il loro utilizzo occorre includere il file string.h
strcpy (s1, s2) copia la stringa s2 in s1
strcat (s1, s2) concatena s2 alla fine di s1
strlen (s) restituisce la lunghezza della stringa s
strcmp (s1, s2) confronta s1 con s2
Le funzioni
Funzioni
4Con il termine funzione si intende, in generale, un operatore che, applicato a certi operandi, consente di calcolare un risultato 4Il linguaggio C consente la definizione di funzioni
4Occorre dichiarare il cosiddetto prototipo della funzione nella sezione delle dichiarazioni globali:
<tipo risultato> <nome funzione> (<elenco parametri>);
dove:
<elenco parametri> ::= <tipo parametro> [<nome parametro>] {,<tipo parametro> [<nome parametro>]}
Funzioni
Esempi: int somma (int m, int n);
int somma (int, int);
int fun (void);
4Occorre definire la funzione
<tipo risultato> <nome funzione> ([<elenco par.>]){
<corpo della funzione>
}
4All’interno del corpo della funzione, si utilizza un’apposita istruzione per uscire dalla funzione e restituirne il risultato:
return<espressione risultato>
Esempio
#include <stdio.h>
int leggi_numero (void);
int max ( int m, int n);
int main () { int a, b;
a = leggi_numero();
b = leggi_numero();
printf (“Il massimo è %d\n”, max (a,b));
return 0;
}
int leggi_numero() { int n;
printf (“Inserire un numero:”);
scanf (“%d”, &n);
return n;
}
int max (int m, int n) { if (m>n) return m;
else return n;
}
Funzioni
4I parametri specificati nella definizione si chiamano parametri formali;
il loro nome è completamente arbitrario.
4Alla chiamata, si specificano i cosiddetti parametri effettivi.
4In C i parametri vengono passati per valore.
4Gli array vengono passati per indirizzo (in realtà si tratta ugualmente di un passaggio per valore, in quanto in C il nome di un array è l’indirizzo del primo elemento)
4Se la funzione modifica il contenuto dell’array, tale modifica si riflette sull’array originario
4Non occorre specificare la dimensione dell’array nell’elenco dei parametri formali
Esempio
/* Restituisce il valore del minimo di un vettore di interi vet: vettore di cui si cerca il minimo
dim: numero di elementi del vettore
*/
int min_ele (int vet[], int dim) { int i, min;
min=vet[0];
for (i=1;i<dim;i++)
if (vet[i]<min) min=vet[i];
return min;
}
Funzioni: passaggio per riferimento
La funzione swap e il passaggio di array
Funzioni con parametri
4 Possono operare su dati diversi per ogni funzione
4 il programma che chiama la funzione deve dichiarare nella chiamata i dati su cui operare
Passaggio parametri per valore (by value)
4
Parametri formali utilizzati nella funzione chiamata
4Parametri effettivi passati per valore dalla funzione
chiamante
ã
I valori dei dati effettivi sono copiati nei parametri formali utilizzati dalla funzione chiamata
o
Nessun effetto provocato da modifiche nel parametro
formale all’interno della funzione si ripercuote sul
parametro reale del programma chiamante
Esempio
4 Si realizzi un programma che legga da tastiera il costo di listino di un prodotto e la percentuale di sconto e visualizzi il prezzo da pagare
4 si può realizzare una funzione che riceva come parametri i due valori e calcoli il prezzo finale
Esempio
/*Funzione con parametri*/
#include<stdio.h>
/*Definizioni generali - variabili globali*/
long int costo;
int percentuale;
long int prezzo_scont(long int valore, int percent) {/*Definizioni interne alla funzione*/
long int val_scont;
/*Corpo della funzione*/
val_scont=valore-(valore*percent/100);
return (val_scont)}
main()
{printf(“Introduci costo e percentuale (interi):\n”);
scanf(“%ld%d”,&costo,&percentuale);
printf(“Prezzo di listino: %ld, sconto: %d%%”, costo, percentuale);
printf(“prezzo finale: %dld\n”, prezzo_scont(costo, percentuale));}
Esempio
4 Parametri formali: valore e percent 4 Parametri effettivi: costo e percentuale
Passaggio dei parametri by reference
4 Cosa succede se la funzione deve restituire più di un dato alla funzione chiamante?
4 Si passa l’indirizzo della cella di memoria in cui è contenuto il risultato
Esempio
int dato2; // definizione di intero
int *ind_dato; // definizione di puntatore ad un intero main()
{ ind_dato=&dato2;//assegna l’indirizzo dato2=5; //assegna un valore intero
*ind_dato=3; // ora dato2 vale 3 }
Esempio
#include <stdio.h>
float un_dato, quadrato, cubo;
void calcola(float valore, float *quad_val, float *cub_val) {*quad_val =valore * valore;
*cub_val=*quad_val * valore;
return;}
main()
{printf(Introduci una dato);
scanf(“%f”, &un_dato);
calcola(un_dato, &quadrato, &cubo);
printf(“Il quadrato di %f e\’ : %f, il cubo %f”,un_dato, quadrato, cubo);}
Osservazione
4 Importante la sintassi, si rischia di effettuare errori che il compilatore non trova
4 Attenzione agli effetti collaterali: occorre valutare che le variazioni introdotte nelle procedure non abbiano ripercussioni indesiderate in altre parti del programma
Esempio: provare la funzione swap
(funzione che commuta il valore fra a e b)
void swap (int a, int b) //a e b passati per valore {int t;
t=a; a=b; b=t;
}
NON SI HA ALCUN EFFETTO
void swap (int *a, int *b)//a e b ora sono dei puntatori { in t;
t=*a; *a=*b; *b=t;
}
chiamando swap(&x,&y) si OTTIENE lo scambio desiderato
Esempio: passaggio di array
#include<stdio.h>
void prova(int a[], int b, int n) main()
{int c[3], d;
c[0]=100; c[1]=15;c[2]=20; d=0;
printf(“Prima: %d,%d,%d,%d\n”, c[0], c[1], c[2], d);
prova(c,d,3);
printf(“Dopo: %d,%d,%d,%d\n”, c[0], c[1], c[2], d);
}
void prova(int a[], int b, int n) //a per riferimento b n per valore {int i;
for (i=1; i<n; i++) a[i]=b;
b =a[0]}
Prima: 100, 15,20, 0 Dopo: 100, 0,0,0
Le strutture
Strutture
4Una struttura è un raggruppamento di variabili sotto un unico nome; le singole variabili si chiamano membri della struttura:
* ESEMPIO
4Una struttura può contenere al suo interno ulteriori sottostrutture
persona:
cognome nome indirizzo data_nascita
indirizzo:
via località provincia CAP
data_nascita:
giorno mese anno
Strutture
4La definizione di una struttura in C avviene nel modo seguente:
struct<nome struttura> ‘{‘
<dichiarazione di variabile>
{ <dichiarazione di variabile> }
‘}’;
* ESEMPIO
struct data_nascita{
int giorno;
int mese;
int anno;
};
equivalentemente:
struct data_nascita { int giorno, mese, anno;
};
Strutture
4La definizione di una struttura non definisce alcuna variabile, ma solo un tipo di dato; per dichiarare variabili di tipo struttura:
struct<nome struttura> <nome variabile> {,<nome variabile>};
* ESEMPIO
struct data_generica{
int giorno;
int mese;
int anno;
};
struct data_generica data_fattura,
data_bolla;
equivalentemente:
struct data_generica { int giorno;
int mese;
int anno;
}data_fattura, data_bolla;
Strutture
4Per fare riferimento ai membri di una struttura , se ne qualifica il nome facendolo precedere dal nome della variabile di struttura di appartenenza, inserendo un punto di separazione
scanf(“%d%d%d”,&data_bolla.giorno,
&data_bolla.mese, &data_bolla.anno);
4È consentito l’assegnamento diretto tra due variabili di struttura dello stesso tipo; ad esempio:
data_fattura=data_bolla;
I File
I File
4normalmente con la parola file (o archivio) si intende un insieme di informazioni, memorizzate su disco magnetico 4le operazioni tipiche che si possono eseguire su di un file
sono:
–lettura di dati in memoria
–scrittura (aggiornamento o aggiunta) di dati dalla memoria
file memoria
lettura
scrittura
I File
4un file è una struttura dinamica, in quanto è possibile aggiungere dei nuovi dati al suo interno, incrementando così la sua dimensione 4per il C, un file non è altro che una sequenza di byte 4esistono due tipi di file in C
– file di testo
•sono strutturati in linee di testo (tipicamente in codice ASCII)
•il C identifica la fine di una linea, con il carattere ‘\n’
•l’effettivo contenuto del file su disco, dipende dal modo in cui il sistema operativo consente di realizzare i file di testo
–file binari
•i byte che vengono letti e scritti, corrispondono all’effettivo contenuto del file:
non viene effettuata alcuna conversione
•anche un file di testo può essere elaborato come file binario: in tal caso si opera sull’effettivo contenuto in byte del file
I File
4più in generale, il C considera file, un qualunque dispositivo di I/O da cui possono essere letti o su cui possono essere scritti dei byte di informazioni
– Es. tastiera, monitor, stampante, file su disco, porta seriale … 4esistono in particolare tre file standard utilizzabili direttamente da parte
di un qualunque programma C:
– stdin (standard input): è il dispositivo standard di input dei dati, normalmente rappresentato dal terminale; viene usato dalle funzioni scanf(), getchar(), gets(), …
– stdout (standard output): è il dispositivo standard di output dei dati, normalmente rappresentato dal monitor del terminale; viene usato dalle funzioni printf(), putchar(), puts(), …
– stderr (standard error): è il dispositivo standard di visualizzazione dei messaggi di errore, normalmente rappresentato dal monitor del terminale
I File
4quando si desidera elaborare un file, occorre dichiarare un puntatore ad una struttura di dati apposita, di nome FILE e definita nel file stdio.h
Es. FILE* mio_file;
4la struttura serve per memorizzare informazioni interne indispensabili per l’elaborazione successiva del file stesso;
chi scrive il programma non è tenuto a conoscerne l’effettivo contenuto
4il puntatore serve, all’interno del programma, per fare riferimento al file interessato, nelle successive operazioni 4tale struttura non deve essere dichiarata per i tre file
standard
I File
4la prima operazione che deve essere effettuata su di un file è la sua apertura
FILE* fopen(char* nomefile, char* modalità);
–nomefile rappresenta il nome effettivo del file
–modalità specifica il modo in cui il file verrà aperto; condiziona le successive operazioni sul file stesso
4la funzione fopen() crea una struttura di dati di tipo FILE, restituisce come risultato il puntatore a tale struttura; in caso di errore (file inesistente, ... ) restituisce null 4i tre file standard, vengono aperti automaticamente
I File
“r” apre un file di testo esistente consente operazioni di lettura si posiziona all’inizio del file
“w” crea un nuovo file di testo consente operazioni di scrittura (aggiunta di linee alla fine del file)
“a” apre un file di testo esistente si posiziona alla fine del file consente operazioni di scrittura (aggiunta di linee alla fine del file)
“r+” apre un file di testo esistente consente operazioni di lettura e di scrittura (in un qualunque punto, con sovrascrittura dei byte preesistenti) si posiziona all’inizio del file
“w+” crea un nuovo file di testo consente operazioni di lettura e di scrittura
“a+” apre un file di testo esistente si posiziona alla fine del file consente operazioni di scrittura
Inserendo la lettera “b” si ottengono le analoghe modalità per i file binari
I File
4Alla fine delle elaborazioni di un file, occorre effettuare l’operazione di chiusura
int fclose (FILE* puntatore)
–libera la struttura di dati abbinata al file
–in caso di scritture, garantisce che tutti i dati scritti sul file, siano effettivamente trasferiti su disco
–ritorna 0 se conclusa correttamente
–comunque, alla terminazione di un programma C, il programma stesso provvede a chiudere tutti gli eventuali file ancora aperti (ma non ne garantisce la corretta scrittura)
File di Testo
4per leggere un carattere da un file di testo, si utilizza la funzione:
int fgetc (FILE* puntatore) –legge un carattere dal file ed avanza sul carattere successivo –restituisce il carattere letto sotto forma di numero int (con i bit oltre
il primo byte, tutti uguali a zero)
–restituisce il carattere ‘\n’ quando viene incontrata la fine di una riga; restituisce ‘\n’ quando è effettivamente incontrato nel file –restituisce un valore apposito, rappresentato dalla costante EOF
(definita in stdio.h, solitamente con il valore -1), per indicare che si è raggiunta la fine del file
Esempio
/* legge i caratteri presenti in un file di testo e li invia al monitor*/
#include <stdio.h>
int main(){
char c,nome[100];
FILE* f;
printf (“Specificare il nome del file:”);
scanf (“%s”, &nome);
if ((f=fopen(nome, “r”)) == NULL) printf (“Errore apertura file\n”);
else{
while((c=fgetc(f))!=EOF) putchar (c);
fclose(f);
} return 0;
}
equivale a:
c=fgetc(f);
while(c!= NULL) { putchar (c);
c=fgetc(f);
}
equivale a:
f=fopen(nome, “r”);
if(f == NULL)
…
File di Testo
4per scrivere un carattere in un file (di testo o binario), si utilizza la funzione:
int fputc(int carattere, FILE* puntatore);
–scrive un carattere nella posizione corrente del file
–ritorna il carattere scritto, in caso di successo, EOF in caso di errore –qualora si scriva il carattere di codice ‘\n’ in un file di testo, si ha
l’effetto di chiudere la linea corrente del file
Esempio
/*aggiunge una riga alla fine di un file di testo, leggendo i caratteri da tastiera*/
#include <stdio.h>
int main(){
char c,nome[100];
FILE* f;
printf (“Specificare il nome del file:”);
scanf (“%s”, &nome);
getchar(); /* elimina ‘\n’ dal buffer della tastiera */
if ((f=fopen(nome, “a”)) == NULL) printf (“Errore apertura file\n”);
else{
do{
c=getchar();
fputc(c, f);
}while (c!=’\n’);
fclose(f);
} return 0;
}
File di Testo
4Per leggere una stringa da un file (di testo o binario), avanzando del numero di caratteri corrispondente, si utilizza la funzione:
char* fgets(char* stringa,int lunghezza,FILE* puntatore);
– occorre specificare la stringa destinata a contenere i caratteri letti ed il numero massimo di caratteri che possono essere letti (compresi i caratteri
‘\n’ e ‘\0’)
– alla fine della stringa letta, viene memorizzato anche il carattere ‘\n’, oltre al carattere di fine stringa ‘\0’
– la funzione termina quando viene letto il carattere ‘\n’ (effettivo o convertito) oppure quando viene esaurita la lunghezza specificata – ritorna NULL in caso di fine file o in caso di errore; (ritorna il puntatore alla
stringa fornita come parametro, in caso di successo)
Esempio
/*legge le righe di un file di testo e le visualizza*/
#include <stdio.h>
int main() {
char nome[100],riga[100];
FILE *f;
printf (“Specificare il nome del file:”);
scanf (“%s”, &nome);
getchar(); /* elimina ‘\n’ dal buffer della tastiera */
if ((f=fopen(nome, “r”)) == NULL) printf (“Errore apertura file\n”);
else{
while (fgets(riga,100,f)!=NULL) printf(“%s”,riga);
fclose(f);
} return 0;}
Il carattere ‘\n’ è già presente nella stringa letta
File di Testo
4per scrivere una stringa in un file (di testo o binario), si utilizza la funzione:
int fputs(const char* stringa,FILE*
puntatore);
–non aggiunge automaticamente il carattere ‘\n’ alla fine della linea –ritorna EOF in caso di errore
Esempio
/* legge delle stringhe e le scrive in un file di testo nuovo; termina quando viene inserita una riga vuota */
#include <stdio.h>
#include <string.h>
int main() { char nome[100],riga[100];
FILE* f;
printf (“Specificare il nome del file:”);
scanf (“%s”, &nome);
getchar(); /* elimina ‘\n’ dal buffer della tastiera */
if ((f=fopen(nome, “w”)) == NULL) printf (“Errore apertura file\n”);
else { do {
gets(riga);
if (riga[0]!=’\0’) { strcat(riga, “\n”);
fputs(riga,f);
}
}while (riga[0]!=’\0’);
fclose(f);
} return 0;}
fscanf e fprintf
4 Sono le analoghe di printf e scanf solo che va specificato il file su cui scrivere o leggere
4 Esempi
– fscanf(miofile, “%d”,&intero);
– fprintf(miofile, “%d\n,”intero);
L’Ordinamento di vettori
l’algoritmo bubble sort
Ordinamento bubble sort
4
Ordinare il vettore 5, 3, 7, 4, 10
4Ciclo di scambi
(1-
ciclo) (2 -
ciclo) (3 -
ciclo)
5, 3, 7, 4, 10 3, 5, 4, 7, 10 3, 5, 4, 7, 10 3, 5, 7, 4, 10J 3, 5, 4, 7, 10 3, 5, 4, 7, 10 3, 5, 7, 4, 10 3, 4, 5, 7, 10 J 3, 5, 4, 7, 10 3, 5, 4, 7, 10 J 3, 4, 5, 7, 10 3, 5, 4, 7, 10 3, 5, 4, 7, 10 3, 4, 5, 7, 10 3, 5, 4, 7, 10partenza
2 e 3 1 e 2
3 e 4 4 e 5
2 scambi 1 scambi 0 scambi
Ordinamento bubble sort
#define MAX 5
#define true 1
#define false 0 float v[MAX];
int size; //dimensione corrente del vettore void bubblesort(int inz, int fine);
void leggi();
void scrivi();
main()
{ printf (“ordinamento di un vettore”);
leggi();
bubblesort(0, size -1);
scrivi();}
Ordinamento bubble sort
void leggi() {int i;
printf(“fornire la lunghezza del vettore < 5\n”);
scanf(“%d”,&size);
for (i=0;i<size;i=i+1)
{printf(“elemento di posto %d valore?\n”, i);
scanf(“%f”,&v[i]); printf(“valore %f\n” v[i]);}
}
void scrivi() {int i;
for (i=0;i<size;i=i+1)
printf(“elemento di posto %d e valore\n”, i, v[i]);
}
Ordinamento bubble sort
void bubblesort(int iniz, int fine) {int nonscambio, i;
float temp;
do{
nonscambio=true;
for (i=iniz; i<fine;i=i+1) {if (v[i]>v[i+1]
{nonscambio=false;
temp=v[i]; v[i]=v[i+1]; v[i+1]=temp;
} } }
while(!nonscambio) }