Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Ver. 2.4.2
Il codice ASCII
Per memorizzare i simboli grafici
corrispondenti ai caratteri bisogna associare
un numero intero a ciascuno di essi
Il codice ASCII /’æski/ (American Standard
Code for Information Interchange) è una
tabella che elenca le corrispondenze tra
simboli grafici e numeri (es. A 65, B 66)
I numeri del Codice ASCII standard sono a 7
bit 27=128 caratteri diversi
Curiosità: il codice ASCII delle cifre 0-9 si può
ottenere dal corrispondente valore in BCD
facendolo precedere dal valore 011:
7 = 0111, 0110111 = 55 (codice ASCII di 7)
3
91
Altri caratteri
90 Z
65 A
Lettere maiuscole (A-Z)
64
58
Altri caratteri
57 9
48 0
Cifre (0-9)
47
33
Altri caratteri
32 Carattere SPAZIO
31
0
Caratteri di controllo
4
Caratteri
Per memorizzare un carattere, il C memorizza
il numero intero corrispondente al suo codice
ASCII ('A' equivale a 65, '0' a 48, ecc.)
Costanti carattere: indicate tra apici singoli
('A'), oppure indicandone il codice ASCII in:
decimale: 65
ottale: '\101'
esadecimale: '\0x41'
Le costanti di tipo carattere vengono anche
chiamate letterali carattere (character literal )
8
Caratteri
Essendo numeri interi, i caratteri possono
essere usati nelle operazioni:
x = c–'0';
se c contiene il codice ASCII di una cifra,
c–'0' ne è il valore corrispondente
Esempio
Se c='7', allora '7'–'0' viene valutato
come 55–48, cioè il valore 7
(il risultato è di tipo int per effetto delle
promozioni integrali)
9
Caratteri
Variabili carattere: variabili di tipo intero su
8 bit, sono definite di tipo char
char y; definizione
y = 'A'; assegnazione con carattere
y = 65; ass. con cod. ASCII decimale
y = '\101'; con cod. ASCII ottale
y = '\0x41'; con cod. ASCII esadecim.
Tutte le assegnazioni precedenti sono
equivalenti ed assegnano il carattere 'A'
(codice ASCII 65) alla variabile y
10
Caratteri
y può essere usata sia come numero (65) sia
come carattere ('A'):
printf("%c ha valore %d\n", y, y);
dove la specifica %c serve per visualizzare il
simbolo corrispondente ad un codice ASCII,
mentre la specifica %d visualizza un numero
intero, questo visualizza:
A ha valore 65
11
Caratteri
Alcuni caratteri speciali si possono anche
ottenere utilizzando le sequenze di escape:
Caratteri speciali: \' \" \? \\
Ad es. per introdurre l’apice in una variabile
char si deve scrivere '\'' dove il carattere di
escape \ permette di considerare l’apice che lo
segue come carattere normale e non come
delimitatore di una costante di tipo carattere
char apice = '\'';
Poiché il carattere \ ha un significato speciale,
quando esso serve come carattere normale
deve essere raddoppiato (anche nelle stringhe)
char backslash = '\\';
12
Caratteri
I caratteri corrispondenti ai caratteri di
controllo del codice ASCII non hanno un
aspetto grafico, ma quando vengono
visualizzati producono un effetto quale un
beep, un ritorno a capo, ecc.
Si possono facilmente ottenere mediante
sequenze di escape (oppure si indicano con il
codice ASCII in decimale, ottale o esadec.):
\a - quando viene visualizzato fa emettere un beep
\n - corrisponde al carattere new line (10)
\r - corrisponde al carattere carriage return (13)
\t - corrisponde al carattere Tab
char beep = '\a';
13
Stringhe
Sono vettori di char terminati dal carattere
null: quello di codice ASCII pari a 0 (non è il
carattere '0' che ha valore 48 nel codice
ASCII, ma il carattere ottale '\0')
C I A O \0 67 73 65 79 0
I L R E ! \0 73 74 32 82 69 33 0
Stringhe costanti
Stringhe costanti
Sono sequenze di char racchiuse da doppi
apici, la stringa "ciao ciao" è composta da
9+1 caratteri, l’ultimo è '\0'
Per includere in una stringa i caratteri \ e " è
necessario precederli con il carattere escape \
"vero\\falso" memorizza: vero\falso
"premi \"invio\" per terminare"
memorizza: premi "invio" per terminare
Lo standard C89 chiama la stringa costante
letterale stringa (string literal ) e afferma che
può contenere almeno 509 char
15
Stringhe costanti
Più stringhe costanti consecutive (separate da
nulla, spazi, Tab o ritorni a capo) vengono
concatenate dal compilatore in una sola:
"ciao" "ciao"
"ciao" "ciao"
viene memorizzata come fosse scritta così:
"ciaociaociaociao" (17 caratteri)
Una stringa costante ha classe di allocazione
static (le classi di allocazione sono descritte
nel set di slide sui puntatori)
16
Stringhe costanti
Anche se un letterale stringa viene
normalmente considerato e usato come
stringa costante, in realtà lo standard C89 non
afferma che non possa essere modificato
Lo standard afferma invece che più letterali
uguali possano essere memorizzati in un’unica
copia e che la modifica di uno abbia un effetto
indeterminato (spesso i compilatori hanno
un’opzione per indicare se i letterali stringa
possano essere modificati o no)
puts("ciao"); C I A O \0
strlen("ciao");
17
Stringhe variabili
Variabili stringa
Sono vettori di char di dimensione fissa
(nota al compile-time), l’ultimo carattere deve
essere il terminatore null '\0'
char nome[15];
definisce una variabile stringa composta di 15
char, ma può contenere fino a 14 caratteri
utili perché deve esserci spazio per il carattere
di terminazione null '\0'
18
Stringhe variabili
Come per i vettori, la dimensione (la
lunghezza massima) di una stringa viene di
solito indicata con una #define
Se è richiesto che la stringa possa contenere
esattamente un certo numero di caratteri utili,
è nella definizione della stringa stessa che si
somma 1 per contenere anche il carattere
null
#define MAXSTR 80
char mystring[MAXSTR+1];
19
Stringhe variabili
Il terminatore permette di occupare solo
parzialmente una stringa (lo spazio relativo ai
restanti caratteri esiste ma è inutilizzato)
nome:
C I A O \0 ? ? ? ? ? ? ? ? ? ?
Stringhe variabili
Essendo una stringa un vettore, i suoi elementi
si indicano con la notazione dei vettori:
nome[0] è il 1o carattere
nome[1] è il 2o carattere
ecc.
I singoli elementi della stringa sono caratteri,
se la stringa s contiene "Ciao":
s[2] vale 'a'
s[0] = 'M'; modifica s in "Miao"
Per assegnare una stringa NON si può scrivere
s="Ciao" ma è necessario usare una
funzione (strcpy, vedere più avanti)
21
Stringhe variabili
Si possono inizializzare le variabili stringa in 2
modi equivalenti:
char s[20]="Ciao";
char s[20]={'C','i','a','o'};
s[4] è '\0' in entrambi i casi: essendo
vettori, se l’inizializzazione non riempie del
tutto la stringa, i caratteri successivi a quelli
indicati sono tutti 0 (che è il valore di '\0')
Si noti che "Ciao" non è un letterale stringa
in quanto non viene memorizzato come tale,
ma i suoi caratteri vengono inseriti in s ed
esistono solo lì
22
Stringhe variabili
Si noti la differenza tra:
'a' il carattere 'a' (il numero 97)
"a" la stringa contenente 'a' e '\0'
Essendo una stringa un vettore di char, il
nome di una stringa viene usato dal
compilatore come sinonimo dell’indirizzo di
memoria del primo carattere
Per quanto non molto utile, anche un letterale
stringa può essere indicizzato:
hex="0123456789ABCDEF"[val_decim];
printf("%d numer%c\n",a,"io"[a==1]);
23
Ritorno a capo
A seconda del sistema operativo utilizzato, il
ritorno a capo è in realtà costituito da una
sequenza di uno o più caratteri:
MS-DOS/Win: CR+LF (codici ASCII 13 e 10: \r\n)
Problemi di I/O
scanf("%d",&x);
gets(s);
Si supponga di inserire un valore e premere
Invio: la scanf legge il valore, ma il ritorno a
capo ‘\n’ (prodotto dal tasto Invio) viene
prelevato (e scartato) dalla gets che quindi
non aspetta altro input e mette in s una
stringa vuota (cioè un carattere ‘\0’):
la gets sembra essere saltata
Bisogna quindi “consumare” il ritorno a capo
inserito dal tasto Invio dopo l’introduzione del
numero da assegnare a x
33
Problemi di I/O
Soluzioni possibili:
1. si aggiunge dopo la specifica %d la specifica %*c
che legge e scarta il successivo carattere in input (il
ritorno a capo): scanf("%d%*c",&x);
2. si aggiunge dopo la specifica %d uno spazio: "%d ",
ma attenzione che un’eventuale printf tra le due
appare eseguita dopo la gets
3. si evita di mescolare scanf e gets:
si usano solo scanf: le specifiche (escluse %c e
gli scanset) scartano i white space iniziali (e ‘\n’)
si usano solo gets: la gets legge una riga e
scarta il ‘\n’ alla fine della riga stessa
4. alcuni compilatori permettono di svuotare i buffer di
input con fflush(stdin) tra la scanf e la gets,
ma fflush su stdin non è standard
34
Problemi di I/O
Si chiede l’introduzione di due caratteri dalla
tastiera (due input diversi) mediante il codice:
puts("Inserisci 1o carattere: ");
scanf("%c", &c);
puts("Inserisci 2o carattere: ");
scanf("%c", &d);
la prima scanf preleva il carattere per c, ma
lascia nel buffer della tastiera il ritorno a capo
e questo viene prelevato dalla seconda scanf
per d, quindi a d viene assegnato il codice del
ritorno a capo
35
Problemi di I/O
Soluzioni possibili:
1. nella seconda scanf si usa “ %c” (spazio iniziale)
2. nella prima scanf si usa “%c%*c”
3. si sostituisce la 2a scanf con:
scanf("%1s",s);
d = s[0];
avendo definito: char s[2];
Diversamente dalla specifica %c, la specifica %s
salta i white space iniziali (compresi eventuali ‘\n’),
%1s indica che si deve prelevare un solo carattere.
Attenzione che %1s produce una stringa: cioè
memorizza il carattere letto e aggiunge il '\0',
bisogna dimensionarla di almeno 2 caratteri
36
Vettori di stringhe
Una matrice di char è un vettore di stringhe:
char str[4][20]={"uno", "due"};
definisce un vettore di 4 stringhe di 20 char
(i caratteri sono inizializzati a ‘\0’ se almeno
parte della matrice viene inizializzata)
Le 4 stringhe sono identificate da str[i] e
utilizzabili come normali stringhe:
scanf("%s", str[2]); es."ciao"
str[3][0]='X';
str:
str[0] u n o \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
str[1] d u e \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
str[2] c i a o \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
str[3] X \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
52
Vettori di stringhe
Per memorizzare una sequenza di N stringhe
di lunghezza LEN in un vettore di stringhe si
può utilizzare il metodo seguente:
char str[N][LEN];
for (i=0; i<N; i++)
gets(str[i]);
53
Esercizi
1. Scrivere un programma che date due
stringhe in input stampi la più lunga. La
prima se sono di uguale lunghezza.
2. Scrivere un programma che date due
stringhe in input stampi la maggiore.
3. Scrivere un programma che chieda in input
una stringa e calcoli da quanti caratteri è
composta (senza usare la funzione strlen
ma cercando il carattere '\0')
4. Scrivere un programma che data una stringa
in input, la converta tutta in maiuscolo.
5. Scrivere un programma che data una stringa
in input verifichi se essa contiene almeno
una ‘A’ tra i primi 10 caratteri.
54
Esercizi
6. Scrivere un programma che richieda in input
una stringa e conti quante cifre essa contiene.
Esempio
“Ciao2004! C6?” deve dare 5.
7. Scrivere un programma che richieda in input
una stringa e conti di quante lettere
maiuscole, lettere minuscole, cifre e altri
caratteri è composta
Esempio
“Ciao2004! C6?” deve dare:
maiuscole:2, minuscole: 3, cifre: 5, altri: 3.
55
Esercizi
8. Scrivere un programma che date in input due
stringhe di lunghezza diversa indichi se la più
corta è contenuta solo una volta nella più
lunga.
9. Scrivere un programma che verifichi se la
stringa data in input è palindroma o no
(“kayak”, “otto”, “elle”, “anilina”).
10. Scrivere un programma che verifichi se la
stringa data è composta di due parti uguali,
trascurando il carattere centrale se la
lunghezza è dispari (es. “CiaoCiao”,
“CiaoXCiao”).
56
Esercizi
11. Un’immagine è composta da 256x256 punti di
colore bianco o nero ed è rappresentata da
una matrice di caratteri. Ogni elemento della
matrice rappresenta un puntino e vale:
‘1’ per rappresentare un punto nero
‘0’ per rappresentare un punto bianco.
Si scriva un programma che codifichi
l’immagine sostituendo, per ciascuna riga di
punti, le sequenze consecutive dello stesso
carattere (‘0’ o ‘1’) con il carattere stesso
seguito dal numero delle sue ripetizioni. Si
ripeta codificando le colonne.
57
Esercizi
Continuazione:
Ad es. l’immagine seguente (solo 6x3):
0000000000 (ci sono 10 zeri)
0111111100 (1 zero, 7 uno, 2 zeri)
0100000100 (1 zero, 1 uno, 5 zeri, 1 uno, 2 zeri)
viene codificata per righe come segue:
0 10
011702
0111051102
e per colonne come segue:
03
0112
011101
...
58
Homework 2
Scrivere un programma che chieda all’utente di
inserire una frase (max 128 caratteri), conti
quante sono le parole (sequenze di lettere
dell’alfabeto) che la compongono e la lunghezza
media delle parole stesse.
Esempio
Se viene dato in input:
Ieri... sono andato a mangiare all'una!
il programma deve indicare che ci sono 7 parole
e che la lunghezza media è 4.14 caratteri.