Sei sulla pagina 1di 14

2

Il codice ASCII
 Per memorizzare i simboli grafici
corrispondenti ai caratteri bisogna associare
un numero intero a ciascuno di essi
I caratteri e le stringhe  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)
Ver. 2.4
 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:
© 2010 - Claudio Fornaro - Corso di programmazione in C
7 = 0111, 0110111 = 55 (codice ASCII di 7)

3 4

Il codice ASCII standard Il codice ASCII standard


127  Contiene i 95 caratteri di base
Altri caratteri
123
122 z
(es. non le lettere accentate)
97 a
Lettere minuscole (a-z)  Ha 4 sezioni importanti:
96
Altri caratteri  Spazio (è il carattere visibile di codice più basso)
91
90 Z  Cifre (0-9 in ordine crescente)
Lettere maiuscole (A-Z)
65 A
64
 Maiuscole (A-Z in ordine cresc.)
58
Altri caratteri  Minuscole (a-z in ordine cresc.)
57 9
48 0
Cifre (0-9)  Le 4 sezioni sono separate
47 da altri caratteri generici
Altri caratteri
33 (punteggiatura, simboli matematici, ecc.)
32 Carattere SPAZIO  Alcuni caratteri speciali (caratteri di controllo)
31
Caratteri di controllo non vengono visualizzati, ma producono un
0
effetto (es. inserire un ritorno a capo, beep)
5 6

Il codice ASCII standard Il codice ASCII esteso


Poiché i bit vengono considerati a gruppi di 8
Char Dec Oct Hex Char Dec Oct Hex Char Dec Oct Hex Char Dec Oct Hex
(nul)
(soh)
0 0000 0x00
1 0001 0x01
(sp)
!
32
33
0040
0041
0x20
0x21
@
A
64
65
0100
0101
0x40
0x41
`
a
96
97
0140
0141
0x60
0x61

(byte) e non di 7, il codice ASCII viene
(stx) 2 0002 0x02 " 34 0042 0x22 B 66 0102 0x42 b 98 0142 0x62
(etx) 3 0003 0x03 # 35 0043 0x23 C 67 0103 0x43 c 99 0143 0x63
(eot) 4 0004 0x04 $ 36 0044 0x24 D 68 0104 0x44 d 100 0144 0x64
(enq)
(ack)
5 0005 0x05
6 0006 0x06
%
&
37
38
0045
0046
0x25
0x26
E
F
69
70
0105
0106
0x45
0x46
e
f
101
102
0145
0146
0x65
0x66 modificato così da usare valori di 8 bit, questo
raddoppia il numero di codici utilizzabili che
(bel) 7 0007 0x07 ' 39 0047 0x27 G 71 0107 0x47 g 103 0147 0x67
(bs) 8 0010 0x08 ( 40 0050 0x28 H 72 0110 0x48 h 104 0150 0x68
(ht) 9 0011 0x09 ) 41 0051 0x29 I 73 0111 0x49 i 105 0151 0x69
(nl)
(vt)
(ff)
10 0012 0x0a
11 0013 0x0b
12 0014 0x0c
*
+
,
42
43
44
0052
0053
0054
0x2a
0x2b
0x2c
J
K
L
74
75
76
0112
0113
0114
0x4a
0x4b
0x4c
j
k
l
106
107
108
0152
0153
0154
0x6a
0x6b
0x6c
passano a 256
I 128 caratteri aggiuntivi (con codice da 128 a
(cr) 13 0015 0x0d - 45 0055 0x2d M 77 0115 0x4d m 109 0155 0x6d
(so) 14 0016 0x0e . 46 0056 0x2e N 78 0116 0x4e n 110 0156 0x6e 
(si) 15 0017 0x0f / 47 0057 0x2f O 79 0117 0x4f o 111 0157 0x6f
(dle) 16 0020 0x10
(dc1) 17 0021 0x11
0
1
48
49
0060
0061
0x30
0x31
P
Q
80
81
0120
0121
0x50
0x51
p
q
112
113
0160
0161
0x70
0x71 255) vengono utilizzati per altri simboli grafici
meno comuni (es. le lettere accentate, à, ë, î)
(dc2) 18 0022 0x12 2 50 0062 0x32 R 82 0122 0x52 r 114 0162 0x72
(dc3) 19 0023 0x13 3 51 0063 0x33 S 83 0123 0x53 s 115 0163 0x73
(dc4) 20 0024 0x14 4 52 0064 0x34 T 84 0124 0x54 t 116 0164 0x74

La parte aggiunta non è standard ed è diversa


(nak) 21 0025 0x15 5 53 0065 0x35 U 85 0125 0x55 u 117 0165 0x75
(syn) 22 0026 0x16
(etb) 23 0027 0x17
6
7
54
55
0066
0067
0x36
0x37
V
W
86
87
0126
0127
0x56
0x57
v
w
118
119
0166
0167
0x76
0x77

per ciascun sistema operativo
(can) 24 0030 0x18 8 56 0070 0x38 X 88 0130 0x58 x 120 0170 0x78
(em) 25 0031 0x19 9 57 0071 0x39 Y 89 0131 0x59 y 121 0171 0x79
(sub) 26 0032 0x1a : 58 0072 0x3a Z 90 0132 0x5a z 122 0172 0x7a

Può essere diversa anche nello stesso sistema


(esc) 27 0033 0x1b ; 59 0073 0x3b [ 91 0133 0x5b { 123 0173 0x7b
(fs) 28 0034 0x1c < 60 0074 0x3c \ 92 0134 0x5c | 124 0174 0x7c 
(gs) 29 0035 0x1d = 61 0075 0x3d ] 93 0135 0x5d } 125 0175 0x7d
(rs)
(us)
30 0036 0x1e
31 0037 0x1f
>
?
62
63
0076
0077
0x3e
0x3f
^
_
94
95
0136
0137
0x5e
0x5f
~ 126
(del) 127
0176
0177
0x7e
0x7f operativo a seconda della lingua

7 8

Caratteri Caratteri
 Per memorizzare un carattere, il C memorizza  Essendo numeri interi, i caratteri possono
il numero intero corrispondente al suo codice essere usati nelle operazioni:
ASCII ('A' equivale a 65, '0' a 48, ecc.) x = c–'0';
 Costanti carattere: indicate tra apici singoli se c contiene il codice ASCII di una cifra,
('A'), oppure indicandone il codice ASCII in: c–'0' ne è il valore corrispondente
 decimale: 65 Esempio
 ottale: '\101' Se c='7', allora '7'–'0' viene valutato
 esadecimale: '\0x41' come 55–48, cioè il valore 7
(il risultato è di tipo int per effetto delle
 Le costanti di tipo carattere vengono anche
promozioni integrali)
chiamate letterali carattere (character literal )
9 10

Caratteri Caratteri
 Variabili carattere: variabili di tipo intero su  y può essere usata sia come numero (65) sia
8 bit, sono definite di tipo char come carattere ('A'):
char y;  definizione printf("%c ha valore %d\n", y, y);
y = 'A';  assegnazione con carattere dove la specifica %c serve per visualizzare il
y = 65;  ass. con cod. ASCII decimale simbolo corrispondente ad un codice ASCII,
y = '\101';  con cod. ASCII ottale mentre la specifica %d visualizza un numero
y = '\0x41';  con cod. ASCII esadecim. intero, questo visualizza:
Tutte le assegnazioni precedenti sono A ha valore 65
equivalenti ed assegnano il carattere 'A'
(codice ASCII 65) alla variabile y

11 12

Caratteri Caratteri
 Alcuni caratteri speciali si possono anche  I caratteri corrispondenti ai caratteri di
ottenere utilizzando le sequenze di escape: controllo del codice ASCII non hanno un
 Caratteri speciali: \' \" \? \\ aspetto grafico, ma quando vengono
 Ad es. per introdurre l’apice in una variabile visualizzati producono un effetto quale un
char si deve scrivere '\'' dove il carattere di beep, un ritorno a capo, ecc.
escape \ permette di considerare l’apice che lo  Si possono facilmente ottenere mediante
segue come carattere normale e non come sequenze di escape (oppure si indicano con il
delimitatore di una costante di tipo carattere codice ASCII in decimale, ottale o esadec.):
char apice = '\''; \a - quando viene visualizzato fa emettere un beep
\n - corrisponde al carattere new line (10)
 Poiché il carattere \ ha un significato speciale, \r - corrisponde al carattere carriage return (13)
quando esso serve come carattere normale \t - corrisponde al carattere Tab
deve essere raddoppiato (anche nelle stringhe)
char backslash = '\\'; char beep = '\a';
13 14

Stringhe Stringhe
 Sono vettori di char terminati da un carattere  Stringhe costanti
di codice ASCII pari a 0 (il terminatore non è il Sono sequenze di caratteri racchiuse da doppi
carattere '0' che ha valore 48 nel codice apici, la stringa "ciao ciao" è composta da
ASCII, ma il carattere '\0') 9+1 caratteri, l’ultimo è '\0'
Per includere in una stringa i caratteri \ e " è
C I A O \0 67 73 65 79 0 necessario precederli dal carattere di escape \
 "vero\\falso" memorizza: vero\falso
I L R E ! \0 73 74 32 82 69 33 0  "premi \"invio\" per terminare"
memorizza: premi "invio" per terminare
 Le terminate da uno 0 vengono anche dette  Una stringa costante viene anche chiamata
stringhe ASCIIZ, il linguaggio C ha solo questo letterale stringa (string literal )
tipo di stringhe

15 16

Stringhe Stringhe
 Più stringhe costanti consecutive (separate da  Variabili stringa
nulla, spazi, Tab o ritorni a capo) vengono Sono vettori di char di dim. fissa, l’ultimo
concatenate dal compilatore in una sola: carattere deve essere il terminatore '\0'
"ciao" "ciao"  char nome[15];
"ciao" "ciao" definisce una variabile stringa composta di 15
viene memorizzata come fosse scritta così: char, può contenere fino a 14 caratteri utili
"ciaociaociaociao" (17 caratteri) (deve esserci spazio per il carattere '\0')
 Una stringa costante è un vettore di char di Il 1o carattere è nome[0], il 2o nome[1], ecc.
classe di allocazione static (quindi non  Il terminatore permette di occupare solo
modificabile) inizializzato con i caratteri dati parzialmente una stringa (lo spazio relativo ai
 Le classi di allocazione sono descritte in altro set di slide restanti caratteri esiste ma è inutilizzato)
(puntatori) nome: C I A O \0 ? ? ? ? ? ? ? ? ? ?
17 18

Stringhe Stringhe
 La lunghezza di una stringa è il numero di  Si possono inizializzare le variabili stringa in 2
caratteri contenuti (fino al '\0' escluso), non modi equivalenti:
char s[20]="Ciao";
la sua “capienza” (nell’es. precedente è 4)
char s[20]={'C','i','a','o'};
 Si noti la differenza tra: Il carattere di posizione 4 (il 5o) è '\0' in
'a'  il carattere 'a' (il numero 97) entrambi i casi: infatti, essendo vettori, se
"a"  la stringa contenente 'a' e '\0' l’inizializzazione non riempie completamente
 Essendo una stringa un vettore di char, il la stringa, i caratteri successivi a quelli indicati
nome di una stringa viene usato dal sono tutti 0 (cioè '\0')
compilatore come sinonimo dell’indirizzo di  I singoli elementi della stringa sono caratteri:
s[2] vale 'a'
memoria del primo carattere s[0] = 'M'; modifica s in "Miao"
 Per assegnare una stringa NON si può
scrivere s="Ciao" ma serve una funzione

19 20

I/O di caratteri <stdio.h> I/O di caratteri <stdio.h>


 printf("%c", varChar);  putchar(varChar);
manda in output il carattere manda in output il carattere
 scanf("%c", &varChar);  varInt = getchar();
legge 1 carattere (anche spazi e ritorni a capo) getchar restituisce il carattere letto o la
e lo mette in varChar, costante EOF per segnalare la fine dell’input,
se viene indicata un’ampiezza (es. %4c) legge varInt deve essere di tipo int per potervi
esattamente quel numero di caratteri (anche memorizzare anche EOF che è di tipo int.
spazi) e li assegna alla STRINGA indicata come EOF è una costante simbolica definita in
parametro, senza aggiungere il '\0': <stdio.h> con una #define, in genere
scanf("%4c", varStringa); vale –1
per saltare gli spazi iniziali si usi %1s
21 22

I/O di stringhe <stdio.h> I/O di stringhe <stdio.h>


 puts(varStringa);  scanf("%s", varStringa);  SENZA &
visualizza varStringa e aggiunge un '\n' alla %s salta i white space (spazi, Tab, '\n', ecc.)
fine (cioè va a capo). Dà EOF in caso di errore iniziali e legge solo fino al primo white space
 gets(varStringa); (che lascia nel buffer), per leggere il primo
legge da tastiera tutta la stringa in input carattere saltando i white space iniziali si usi
(spazi e Tab inclusi) fino al ritorno a capo %1s (richiede una variabile stringa)
incluso, la mette in varStringa senza il '\n',  Un qualsiasi white space nella stringa di
aggiunge '\0' alla fine.
formato richiede che tutti i white space in quel
Dà NULL in caso di errore o di fine file
punto dell’input vengano saltati (quindi anche
 printf("%s", varStringa); il carattere '\n' non viene considerato come
%s visualizza una stringa (che può contenere
carattere ordinario: non indica affatto alla
spazi, Tab, '\n', ecc.) fino al '\0' o al
scanf che deve attendere un ritorno a capo)
numero di caratteri indicato (es. %4s)

23 24

I/O di stringhe <stdio.h> I/O di stringhe <stdio.h>


 Una specifica di conversione della forma  Per specificare il complementare di uno
%[abc] equivale a una %s salvo che: scanset si usa il carattere ^ come segue:
 si ferma solo quando trova un carattere diverso da %[^abc]
quelli dell’insieme (scanset ) indicati tra le parentesi la lettura si ferma solo quando trova un
quadre (notare che lo scanset può includere lo carattere uguale a uno di quelli indicati tra le
spazio e il ritorno a capo)
parentesi quadre.
 non salta i white-space iniziali
Se si dà in input “albero” alla funzione:
Esempio scanf("%[^nmrst]", s);
scanf("%[abcfrq]", s);
s contiene “albe” mentre “ro” resta
Se si dà in input “abbaino”, s contiene “abba”
disponibile per le successive funzioni di input
mentre “ino” resta disponibile per le successive
funzioni di input
25 26

I/O di stringhe <stdio.h> I/O di stringhe <stdio.h>


 Per leggere una stringa fino a fine riga  Se si danno in input più caratteri di quelli che
utilizzando una scanf si può quindi utilizzare la variabile stringa può contenere, si sfora la
la specifica stringa (buffer overflow ) e si possono avere
%[^\n]%*c comportamenti anomali (vedere i vettori)
che legge tutti i caratteri che trova finché non  Soluzione non preventiva:
incontra il ritorno a capo '\n',  richiedere al compilatore di aggiungere controlli
opportuni (il linguaggio C standard non li prevede)
la parte %*c legge e scarta (non memorizza)
 Soluzioni preventive:
il ritorno a capo
 Non si può evitare il problema della gets, ma
questa può essere sostituita da una fgets nella
quale invece si può specificare il numero massimo
di caratteri da leggere (vedere slide sui file)
 Se si usa una scanf, si può specificare la
dimensione massima del campo in input: es. %20s

27 28

Ritorno a capo Problemi di I/O


 A seconda del sistema operativo utilizzato, il  scanf("%d",&x);
ritorno a capo è in realtà costituito da una gets(s);
sequenza di uno o più caratteri: Si supponga di inserire un valore e premere
 MS-DOS/Win: CR+LF (codici ASCII 13 e 10: \r\n) Invio: la scanf legge il valore, ma il ritorno a
 Unix/Linux: LF (codice 10: \n)
capo ‘\n’ (prodotto dal tasto Invio) viene
prelevato (e scartato) dalla gets che quindi
 Le funzioni di I/O considerano in carattere ‘\n’ non aspetta altro input e mette in s una
indicato nel codice C come riferimento stringa vuota (cioè un carattere ‘\0’):
generico al “ritorno a capo”: la gets sembra essere saltata
 in input la sequenza di ritorno a capo viene
trasformata in ‘\n’  Bisogna quindi “consumare” il ritorno a capo
 in output il carattere ‘\n’ viene sostituito con la dato dopo l’introduzione del numero da
sequenza propria del sistema operativo assegnare a x
29 30

Problemi di I/O Problemi di I/O


 Soluzioni possibili:  Si chiede l’introduzione di due caratteri dalla
1. si aggiunge dopo la specifica %d la specifica %*c tastiera (due input diversi) mediante il codice:
che legge e scarta il successivo carattere in input puts("Inserisci 1o carattere: ");
(il ritorno a capo): scanf("%d%*c",&x);
scanf("%c", &c);
2. si previene il problema evitando di mescolare
scanf e gets: puts("Inserisci 2o carattere: ");
 si usano solo scanf: risolve il problema perché scanf("%c", &d);
le specifiche (esclusa %c) scartano i white space la prima scanf preleva il carattere per c, ma
iniziali (tra cui il ‘\n’)
lascia nel buffer della tastiera il ritorno a capo
 si usano solo gets: risolve il problema perché
la funzione gets legge una riga e scarta il e questo viene prelevato dalla seconda per d,
ritorno a capo ‘\n’ alla fine della riga stessa quindi a d viene assegnato il codice del ritorno
3. alcuni compilatori permettono di svuotare i buffer a capo (in realtà viene assegnato il secondo
di input con fflush(stdin) tra la scanf e la dei due se il ritorno a capo è la coppia CR+LF)
gets, ma fflush su stdin non è standard

31 32

Problemi di I/O Libreria caratteri <ctype.h>


 Soluzioni possibili:  Le seguenti funzioni danno risultato vero
1. nella prima scanf si usa %c%*c che legge ed (valore !=0) se il carattere c è del tipo indicato
elimina il \n  isdigit(c)  cifra decimale
 isalpha(c)  lettera
2. si sostituisce la 2a scanf con:
 isalnum(c)  carattere alfanumerico
scanf("%1s",s);
 isxdigit(c) cifra esadecimale
d = s[0];
 islower(c)  lettera minuscola
avendo definito: char s[2];
Questo funziona in quanto la specifica %s legge  isupper(c)  lettera maiuscola

caratteri dopo aver saltato i white space (anche  iscntrl(c)  carattere di controllo

eventuali ‘\n’), in questo caso deve prelevare un  isspace(c)  white space (' ','\t','\n',...)

solo carattere.  isprint(c)  char stampabile, incluso lo spazio


Attenzione che %1s produce una stringa (e non un  isgraph(c)  char stampabile, escluso lo spazio
carattere) e questa è composta dal carattere letto  ispunct(c)  stampabile, no spazio, no alfanum
e dal carattere di terminazione '\0' if (isdigit(c)) printf("e’ una cifra");
33 34

Libreria caratteri <ctype.h> Funzioni su stringhe <stdlib.h>


 Le seguenti funzioni producono un valore int  varInt = atoi(stringa)
contenente il codice ASCII del carattere c converte stringa in int
eventualmente convertito, se possibile: x=atoi("123");  123 in complem. a 2
 toupper(c)  in maiuscolo  varLong = atol(stringa)
 tolower(c)  in minuscolo converte stringa in long
Altrimenti il valore prodotto resta c (invariato) y=atol("123");  123 in complem. a 2
 Se si vuole convertire in maiuscolo/minuscolo  varDouble = atof(stringa)
tutta una stringa è necessario applicare la converte stringa in double
funzione a ciascuno dei caratteri: z=atof("1.23E5");  1.23×105 in
for (i=0; i<strlen(s); i++) floating point
s[i] = (char)toupper(s[i]);
notare il cast: toupper produce un int

35 36

Confronto tra stringhe Libreria stringhe <string.h>


 Avviene confrontando i caratteri di posizione Lunghezza di una stringa
corrispondente delle due stringhe secondo i  strlen(str)
loro codici ASCII ( “< ” significa “precede”) restituisce un valore intero pari alla lunghezza
“cane” < “gatto” di str ('\0' escluso), il tipo restituito non è
“cane” > “Gatto” int, ma size_t: si tratta di un tipo adatto a
“cane” < “cavallo” contenere la lunghezza di una stringa sul
compilatore in uso (su alcuni potrebbe essere
“cavallo” < “cavallone” equivalente ad un int, su altri ad un long)
“cavallo” < “cavallo ” int l;
“ cavallo” < “cavallo” char s[30]="ciao";
“21” > “123”  Attenzione! l=strlen(s);  l vale 4
37 38

Libreria stringhe <string.h> Libreria stringhe <string.h>


Copia di una stringa Copia parziale di una stringa
 strcpy(str1,str2)  strncpy(str1,str2,n)
copia str2 in str1 ('\0' incluso) copia i primi n caratteri di str2 in str1 (quelli
presenti se è più corta), non aggiunge il '\0'
Il modo corretto di cambiare valore ad una finale se non è tra i primi n caratteri di str2
variabile stringa è dunque il seguente: char s[30]="hello";
char s[30]; strncpy(s, "ciao", 4);  "ciaoo"
strcpy(s, "ciao"); strncpy(s, "hi", 2);  "hiaoo"
Non è invece corretto scrivere: Mentre
s = "ciao"; char s[30]="buongiorno";
Solo nell’inizializzazione si può scrivere: strcpy(s, "ciao");  "ciao"
char s[30] = "ciao";

39 40

Libreria stringhe <string.h> Libreria stringhe <string.h>


Concatenazione di stringhe Confronto tra stringhe
 strcat(str1,str2)  strcmp(str1,str2)
concatena str2 alla fine di str1 ('\0' incluso) confronta str1 e str2 in base ai codici ASCII,
char s[30]="dove", t[30]=" vai"; restituisce un intero:
strcat(s,t);  s vale "dove vai"  minore di 0 se str1<str2
 strncat(str1,str2,n)  uguale a 0 se str1=str2
concatena i primi n caratteri di str2 alla fine di  maggiore di 0 se str1 > str2
str1 (quelli presenti se è più corta), non  strncmp(str1,str2,n)
aggiunge il '\0' finale se non è tra i primi n confronta i primi n caratteri di str1 e str2
caratteri di str2 (quelli presenti se almeno una è più corta)
41 42

Libreria stringhe <string.h> Libreria stringhe <string.h>


Ricerca in stringhe Ricerca in stringhe
 strchr(str, carattere)  Le funzioni di ricerca (strchr, strrchr,
cerca carattere in str a partire dal suo primo strstr, strtok, ecc.) in realtà restituiscono
carattere all’ultimo, dà NULL se non lo trova
l’indirizzo di memoria (“il puntatore”) a
if (strchr(s, 'z') != NULL) quanto trovato e NULL se non lo trovano
printf("Trovata una z!");
 strrchr(str, carattere)
cerca carattere in str a partire dal suo ultimo
carattere al primo, dà NULL se non lo trova
 strstr(str1, str2)
cerca str2 in str1, dà NULL se non la trova
if (strstr(s, "ciao") != NULL)
printf("Trovata stringa ciao!");

43 44

I/O da/su stringhe <stdio.h> I/O da/su stringhe <stdio.h>


 sscanf(stringa, formato, variabili);  Esempio
identica alla scanf, ma preleva da stringa i gets(s);
if (sscanf(s,"%d%d",&a,&b)==2) ...
caratteri come se provenissero dalla tastiera)
 s  “abcd ...”
 Esempio s non contiene valori numerici, nessuna delle
se stg contiene “12 ciao 23.2”, la funzione: variabili viene assegnata e la sscanf restituisce 0
sscanf(stg, "%d%s%f", &a, s, &b);  s  “12 abcd ...”
s contiene 1 solo valore, questo viene assegnato ad
legge e assegna 12 ad a, “ciao” ad s, 23.2 a b a (b resta invariato) e la sscanf restituisce 1,
 Utile per analizzare (parsing) una riga di cui  s  “12 23 abcd ...”
s contiene 2 valori, questi sono assegnati ad a e a
non è noto a priori il numero di elementi che la b e la sscanf restituisce 2
compongono (per sapere quanti sono i valori  s  “12 23 34 abcd ...”
letti si valuta il valore restituito dalla sscanf) s contiene più di 2 valori, i primi due sono
assegnati ad a e a b, i restanti non vengono
considerati e la sscanf restituisce 2
45 46

I/O da/su stringhe <stdio.h> Altre funzioni di parsing


 sprintf(stringa, formato, variabili);  Oltre alla sscanf, per la suddivisione
identica alla printf, ma “scrive” in stringa i (parsing) di una stringa composta da più
caratteri che la printf manderebbe su parti (token) si possono usare le seguenti
stdout (video) funzioni (si rimanda ad altra documentazione
 Esempio per i dettagli, vedere bibliografia):
se g contiene 23 e m contiene “febbraio”  In <string.h>:
sprintf(str, "Il %d %s", g, m); strspn, strcspn, strpbrk, strtok
mette in str: “Il 23 febbraio”  In <stdlib.h> (token di tipo numerico):
strtod, strtol, strtoul
 Utile per assemblare una stringa composta da
parti di tipo diverso provenienti da variabili

47 48

Vettori di stringhe Vettori di stringhe


 Una matrice di char è un vettore di stringhe:  Per memorizzare una sequenza di N stringhe
char str[4][20]={"uno", "due"}; di lunghezza LEN in un vettore di stringhe si
definisce un vettore di 4 stringhe di 20 char può utilizzare il metodo seguente:
(i caratteri sono inizializzati a ‘\0’ se almeno char str[N][LEN];
parte della matrice viene inizializzata) for (i=0; i<N; i++)
Le 4 stringhe sono identificate da str[i] e gets(str[i]);
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
49 50

Esercizi Esercizi
1. Scrivere un programma che date due 6. Scrivere un programma che richieda in input
stringhe in input stampi la più lunga. La una stringa e conti quante cifre essa contiene.
prima se sono di uguale lunghezza.
Esempio
2. Scrivere un programma che date due “Ciao2004! C6?” deve dare 5.
stringhe in input stampi la maggiore.
3. Scrivere un programma che chieda in input 7. Scrivere un programma che richieda in input
una stringa e calcoli da quanti caratteri è una stringa e conti di quante lettere
composta (senza usare la funzione strlen maiuscole, lettere minuscole, cifre e altri
ma cercando il carattere '\0') caratteri è composta
4. Scrivere un programma che data una stringa Esempio
in input, la converta tutta in maiuscolo. “Ciao2004! C6?” deve dare:
5. Scrivere un programma che data una stringa maiuscole:2, minuscole: 3, cifre: 5, altri: 3.
in input verifichi se essa contiene almeno
una ‘A’ tra i primi 10 caratteri.

51 52

Esercizi Esercizi
8. Scrivere un programma che date in input due 11. Un’immagine è composta da 256x256 punti di
stringhe di lunghezza diversa indichi se la più colore bianco o nero ed è rappresentata da
corta è contenuta solo una volta nella più una matrice di caratteri. Ogni elemento della
lunga. matrice rappresenta un puntino e vale:
9. Scrivere un programma che verifichi se la ‘1’ per rappresentare un punto nero
stringa data in input è palindroma o no ‘0’ per rappresentare un punto bianco.
(“kayak”, “otto”, “elle”, “anilina”). Si scriva un programma che codifichi
10. Scrivere un programma che verifichi se la l’immagine sostituendo, per ciascuna riga di
stringa data è composta di due parti uguali, punti, le sequenze consecutive dello stesso
trascurando il carattere centrale se la carattere (‘0’ o ‘1’) con il carattere stesso
lunghezza è dispari (es. “CiaoCiao”, seguito dal numero delle sue ripetizioni. Si
“CiaoXCiao”). ripeta codificando le colonne.
53 54

Esercizi Homework 2
Continuazione: Scrivere un programma che chieda all’utente di
Ad es. l’immagine seguente (solo 6x3): inserire una frase (max 128 caratteri), conti
0000000000 (ci sono 10 zeri) quante sono le parole (sequenze di lettere
0111111100 (1 zero, 7 uno, 2 zeri) dell’alfabeto) che la compongono e la lunghezza
0100000100 (1 zero, 1 uno, 5 zeri, 1 uno, 2 zeri)
media delle parole stesse.
viene codificata per righe come segue:
0 10
Esempio
011702 Se viene dato in input:
0111051102 Ieri... sono andato a mangiare all'una!
e per colonne come segue: il programma deve indicare che ci sono 7 parole
03 e che la lunghezza media è 4.14 caratteri.
0112
011101
...