Lezioni di programmazione in c le stringhe By Cristian Randieri -

48
LEZIONI DI PROGRAMMAZIONE IN “Le stringhe” Ing. Cristian Randieri Università degli Studi di Catania Istituto Nazionale di Fisica Nucleare (INFN)

Transcript of Lezioni di programmazione in c le stringhe By Cristian Randieri -

LEZIONI DI PROGRAMMAZIONE IN

ldquoLe stringherdquo

Ing Cristian RandieriUniversitagrave degli Studi di Catania

Istituto Nazionale di Fisica Nucleare (INFN)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Introduzione

In C non esiste un vero e proprio tipo di dato ldquoStringardquo

Le stringhe sono gestite dal compilatore come sequenze di caratteri cioegrave di dati di tipo char

Esistono due metodi comunemente utilizzati per dichiarare e manipolare stringhe nei programmi ovvero mediante lrsquouso degli array

dei puntatori

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e gli array

In C uno degli utilizzi degli array ad una dimensione riguarda la conservazione in memoria di stringhe di caratteri queste in C sono array di tipo carattere la cui fine egrave segnalata da un carattere null (carattere terminatore) indicato come 0

Il carattere null egrave il primo codice ASCII corrispondente al valore binario 00000000 e non ha niente a che vedere con il carattere 0che ha in ASCII codice binario 00110000

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

char a[10]

dichiara un vettore costituito da un massimo di dieci caratteri e

char frase[] = Oggi cegrave il sole

dichiara larray monodimensionale frase il cui numero di caratteri egrave determinato dalla quantitagrave di caratteri presenti fra doppi apici piugrave uno (il carattere null che chiude la stringa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Assegnazione di valori

Egrave importante notare la differenza tra le due assegnazioni

char a = r

char b[] = r

Nel primo caso viene assegnato il solo carattere r nel secondo la stringa r0 In definitiva se si vuole fare riferimento ad un solo carattere questo deve essere racchiuso fra apici singoli se invece si vuole fare riferimento ad una stringa occorre racchiuderla fra doppi apici

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzioni per il trattamento delle stringhe

Nonostante il linguaggio C non possieda un dato di tipo stringa sono disponibili parecchie funzioni specifiche per il trattamento di questrsquoultime

gets e puts

strcpy

strcat strlen e strcmp

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzioni ldquogetsrdquo e ldquoputsrdquo

Le funzioni gets e puts sono funzioni specializzate nellinput e output di una stringa Il programma seguente riceve in input una stringa e subito dopo la rimanda in output

Notare che in queste istruzioni si fa riferimento alla stringa nel suo complesso e quindi viene utilizzato il nome

include ltstdiohgt

main()

char s[80] dichiara la stringa

gets(s) riceve linput

puts(s) fornisce loutput

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Altre funzioni per il trattamento delle stringhesono disponibili per usi particolari a patto chesi includa nel programma la libreria delle

funzioni ldquostringrdquo mediante la seguente istruzione

include ltstringhgt

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcpyrdquo

Questa funzione copia una stringa in unaltra

Puograve essere utilizzata per esempio per assegnare un valore a una stringa La sua sintassi egrave

strcpy(s1s2)

Si puograve immaginare che tale funzione equivale come effetto allassegnamento nelle variabili di altro tipo (in altri termini egrave come se si scrivesse s1=s2) assegna cioegrave alla stringa s1 il valore contenuto in s2

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcatrdquo

La funzione

strcat(s1s2)

concatena la stringa s2 alla fine della stringa s1

strcpy(s1buon) stringa specificata

in s1

strcpy(s2giorno) lo stesso per s2

strcat(s1s2) s1 conterragrave buongiorno

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione rdquo strlen rdquo

La funzione

strlen(s1)

restituisce un valore numerico che rappresenta la lunghezza della stringa s1

Es a=strlen (s1)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

La funzione

strcmp(s1s2)

puograve essere utilizzata per effettuare comparazioni sul contenuto di due stringhe In particolare tale funzione

Restituisce un valore positivo se vale s1gts2

Restituisce un valore negativo se vale s1lts2

Restituisce 0 se s1 ed s2 sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

Per tenere conto mnemonicamente di tali valori basta pensare al confronto come ad una sottrazione fra lrsquoaltro ciograve egrave non egrave molto distante da quello che avviene in effetti

Se da s1 si sottrae s2 si avragrave un valore positivo nel caso s1gts2 negativo se s1lts2 e nullo se sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Introduzione

In C non esiste un vero e proprio tipo di dato ldquoStringardquo

Le stringhe sono gestite dal compilatore come sequenze di caratteri cioegrave di dati di tipo char

Esistono due metodi comunemente utilizzati per dichiarare e manipolare stringhe nei programmi ovvero mediante lrsquouso degli array

dei puntatori

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e gli array

In C uno degli utilizzi degli array ad una dimensione riguarda la conservazione in memoria di stringhe di caratteri queste in C sono array di tipo carattere la cui fine egrave segnalata da un carattere null (carattere terminatore) indicato come 0

Il carattere null egrave il primo codice ASCII corrispondente al valore binario 00000000 e non ha niente a che vedere con il carattere 0che ha in ASCII codice binario 00110000

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

char a[10]

dichiara un vettore costituito da un massimo di dieci caratteri e

char frase[] = Oggi cegrave il sole

dichiara larray monodimensionale frase il cui numero di caratteri egrave determinato dalla quantitagrave di caratteri presenti fra doppi apici piugrave uno (il carattere null che chiude la stringa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Assegnazione di valori

Egrave importante notare la differenza tra le due assegnazioni

char a = r

char b[] = r

Nel primo caso viene assegnato il solo carattere r nel secondo la stringa r0 In definitiva se si vuole fare riferimento ad un solo carattere questo deve essere racchiuso fra apici singoli se invece si vuole fare riferimento ad una stringa occorre racchiuderla fra doppi apici

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzioni per il trattamento delle stringhe

Nonostante il linguaggio C non possieda un dato di tipo stringa sono disponibili parecchie funzioni specifiche per il trattamento di questrsquoultime

gets e puts

strcpy

strcat strlen e strcmp

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzioni ldquogetsrdquo e ldquoputsrdquo

Le funzioni gets e puts sono funzioni specializzate nellinput e output di una stringa Il programma seguente riceve in input una stringa e subito dopo la rimanda in output

Notare che in queste istruzioni si fa riferimento alla stringa nel suo complesso e quindi viene utilizzato il nome

include ltstdiohgt

main()

char s[80] dichiara la stringa

gets(s) riceve linput

puts(s) fornisce loutput

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Altre funzioni per il trattamento delle stringhesono disponibili per usi particolari a patto chesi includa nel programma la libreria delle

funzioni ldquostringrdquo mediante la seguente istruzione

include ltstringhgt

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcpyrdquo

Questa funzione copia una stringa in unaltra

Puograve essere utilizzata per esempio per assegnare un valore a una stringa La sua sintassi egrave

strcpy(s1s2)

Si puograve immaginare che tale funzione equivale come effetto allassegnamento nelle variabili di altro tipo (in altri termini egrave come se si scrivesse s1=s2) assegna cioegrave alla stringa s1 il valore contenuto in s2

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcatrdquo

La funzione

strcat(s1s2)

concatena la stringa s2 alla fine della stringa s1

strcpy(s1buon) stringa specificata

in s1

strcpy(s2giorno) lo stesso per s2

strcat(s1s2) s1 conterragrave buongiorno

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione rdquo strlen rdquo

La funzione

strlen(s1)

restituisce un valore numerico che rappresenta la lunghezza della stringa s1

Es a=strlen (s1)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

La funzione

strcmp(s1s2)

puograve essere utilizzata per effettuare comparazioni sul contenuto di due stringhe In particolare tale funzione

Restituisce un valore positivo se vale s1gts2

Restituisce un valore negativo se vale s1lts2

Restituisce 0 se s1 ed s2 sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

Per tenere conto mnemonicamente di tali valori basta pensare al confronto come ad una sottrazione fra lrsquoaltro ciograve egrave non egrave molto distante da quello che avviene in effetti

Se da s1 si sottrae s2 si avragrave un valore positivo nel caso s1gts2 negativo se s1lts2 e nullo se sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e gli array

In C uno degli utilizzi degli array ad una dimensione riguarda la conservazione in memoria di stringhe di caratteri queste in C sono array di tipo carattere la cui fine egrave segnalata da un carattere null (carattere terminatore) indicato come 0

Il carattere null egrave il primo codice ASCII corrispondente al valore binario 00000000 e non ha niente a che vedere con il carattere 0che ha in ASCII codice binario 00110000

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

char a[10]

dichiara un vettore costituito da un massimo di dieci caratteri e

char frase[] = Oggi cegrave il sole

dichiara larray monodimensionale frase il cui numero di caratteri egrave determinato dalla quantitagrave di caratteri presenti fra doppi apici piugrave uno (il carattere null che chiude la stringa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Assegnazione di valori

Egrave importante notare la differenza tra le due assegnazioni

char a = r

char b[] = r

Nel primo caso viene assegnato il solo carattere r nel secondo la stringa r0 In definitiva se si vuole fare riferimento ad un solo carattere questo deve essere racchiuso fra apici singoli se invece si vuole fare riferimento ad una stringa occorre racchiuderla fra doppi apici

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzioni per il trattamento delle stringhe

Nonostante il linguaggio C non possieda un dato di tipo stringa sono disponibili parecchie funzioni specifiche per il trattamento di questrsquoultime

gets e puts

strcpy

strcat strlen e strcmp

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzioni ldquogetsrdquo e ldquoputsrdquo

Le funzioni gets e puts sono funzioni specializzate nellinput e output di una stringa Il programma seguente riceve in input una stringa e subito dopo la rimanda in output

Notare che in queste istruzioni si fa riferimento alla stringa nel suo complesso e quindi viene utilizzato il nome

include ltstdiohgt

main()

char s[80] dichiara la stringa

gets(s) riceve linput

puts(s) fornisce loutput

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Altre funzioni per il trattamento delle stringhesono disponibili per usi particolari a patto chesi includa nel programma la libreria delle

funzioni ldquostringrdquo mediante la seguente istruzione

include ltstringhgt

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcpyrdquo

Questa funzione copia una stringa in unaltra

Puograve essere utilizzata per esempio per assegnare un valore a una stringa La sua sintassi egrave

strcpy(s1s2)

Si puograve immaginare che tale funzione equivale come effetto allassegnamento nelle variabili di altro tipo (in altri termini egrave come se si scrivesse s1=s2) assegna cioegrave alla stringa s1 il valore contenuto in s2

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcatrdquo

La funzione

strcat(s1s2)

concatena la stringa s2 alla fine della stringa s1

strcpy(s1buon) stringa specificata

in s1

strcpy(s2giorno) lo stesso per s2

strcat(s1s2) s1 conterragrave buongiorno

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione rdquo strlen rdquo

La funzione

strlen(s1)

restituisce un valore numerico che rappresenta la lunghezza della stringa s1

Es a=strlen (s1)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

La funzione

strcmp(s1s2)

puograve essere utilizzata per effettuare comparazioni sul contenuto di due stringhe In particolare tale funzione

Restituisce un valore positivo se vale s1gts2

Restituisce un valore negativo se vale s1lts2

Restituisce 0 se s1 ed s2 sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

Per tenere conto mnemonicamente di tali valori basta pensare al confronto come ad una sottrazione fra lrsquoaltro ciograve egrave non egrave molto distante da quello che avviene in effetti

Se da s1 si sottrae s2 si avragrave un valore positivo nel caso s1gts2 negativo se s1lts2 e nullo se sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

char a[10]

dichiara un vettore costituito da un massimo di dieci caratteri e

char frase[] = Oggi cegrave il sole

dichiara larray monodimensionale frase il cui numero di caratteri egrave determinato dalla quantitagrave di caratteri presenti fra doppi apici piugrave uno (il carattere null che chiude la stringa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Assegnazione di valori

Egrave importante notare la differenza tra le due assegnazioni

char a = r

char b[] = r

Nel primo caso viene assegnato il solo carattere r nel secondo la stringa r0 In definitiva se si vuole fare riferimento ad un solo carattere questo deve essere racchiuso fra apici singoli se invece si vuole fare riferimento ad una stringa occorre racchiuderla fra doppi apici

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzioni per il trattamento delle stringhe

Nonostante il linguaggio C non possieda un dato di tipo stringa sono disponibili parecchie funzioni specifiche per il trattamento di questrsquoultime

gets e puts

strcpy

strcat strlen e strcmp

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzioni ldquogetsrdquo e ldquoputsrdquo

Le funzioni gets e puts sono funzioni specializzate nellinput e output di una stringa Il programma seguente riceve in input una stringa e subito dopo la rimanda in output

Notare che in queste istruzioni si fa riferimento alla stringa nel suo complesso e quindi viene utilizzato il nome

include ltstdiohgt

main()

char s[80] dichiara la stringa

gets(s) riceve linput

puts(s) fornisce loutput

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Altre funzioni per il trattamento delle stringhesono disponibili per usi particolari a patto chesi includa nel programma la libreria delle

funzioni ldquostringrdquo mediante la seguente istruzione

include ltstringhgt

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcpyrdquo

Questa funzione copia una stringa in unaltra

Puograve essere utilizzata per esempio per assegnare un valore a una stringa La sua sintassi egrave

strcpy(s1s2)

Si puograve immaginare che tale funzione equivale come effetto allassegnamento nelle variabili di altro tipo (in altri termini egrave come se si scrivesse s1=s2) assegna cioegrave alla stringa s1 il valore contenuto in s2

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcatrdquo

La funzione

strcat(s1s2)

concatena la stringa s2 alla fine della stringa s1

strcpy(s1buon) stringa specificata

in s1

strcpy(s2giorno) lo stesso per s2

strcat(s1s2) s1 conterragrave buongiorno

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione rdquo strlen rdquo

La funzione

strlen(s1)

restituisce un valore numerico che rappresenta la lunghezza della stringa s1

Es a=strlen (s1)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

La funzione

strcmp(s1s2)

puograve essere utilizzata per effettuare comparazioni sul contenuto di due stringhe In particolare tale funzione

Restituisce un valore positivo se vale s1gts2

Restituisce un valore negativo se vale s1lts2

Restituisce 0 se s1 ed s2 sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

Per tenere conto mnemonicamente di tali valori basta pensare al confronto come ad una sottrazione fra lrsquoaltro ciograve egrave non egrave molto distante da quello che avviene in effetti

Se da s1 si sottrae s2 si avragrave un valore positivo nel caso s1gts2 negativo se s1lts2 e nullo se sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Assegnazione di valori

Egrave importante notare la differenza tra le due assegnazioni

char a = r

char b[] = r

Nel primo caso viene assegnato il solo carattere r nel secondo la stringa r0 In definitiva se si vuole fare riferimento ad un solo carattere questo deve essere racchiuso fra apici singoli se invece si vuole fare riferimento ad una stringa occorre racchiuderla fra doppi apici

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzioni per il trattamento delle stringhe

Nonostante il linguaggio C non possieda un dato di tipo stringa sono disponibili parecchie funzioni specifiche per il trattamento di questrsquoultime

gets e puts

strcpy

strcat strlen e strcmp

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzioni ldquogetsrdquo e ldquoputsrdquo

Le funzioni gets e puts sono funzioni specializzate nellinput e output di una stringa Il programma seguente riceve in input una stringa e subito dopo la rimanda in output

Notare che in queste istruzioni si fa riferimento alla stringa nel suo complesso e quindi viene utilizzato il nome

include ltstdiohgt

main()

char s[80] dichiara la stringa

gets(s) riceve linput

puts(s) fornisce loutput

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Altre funzioni per il trattamento delle stringhesono disponibili per usi particolari a patto chesi includa nel programma la libreria delle

funzioni ldquostringrdquo mediante la seguente istruzione

include ltstringhgt

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcpyrdquo

Questa funzione copia una stringa in unaltra

Puograve essere utilizzata per esempio per assegnare un valore a una stringa La sua sintassi egrave

strcpy(s1s2)

Si puograve immaginare che tale funzione equivale come effetto allassegnamento nelle variabili di altro tipo (in altri termini egrave come se si scrivesse s1=s2) assegna cioegrave alla stringa s1 il valore contenuto in s2

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcatrdquo

La funzione

strcat(s1s2)

concatena la stringa s2 alla fine della stringa s1

strcpy(s1buon) stringa specificata

in s1

strcpy(s2giorno) lo stesso per s2

strcat(s1s2) s1 conterragrave buongiorno

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione rdquo strlen rdquo

La funzione

strlen(s1)

restituisce un valore numerico che rappresenta la lunghezza della stringa s1

Es a=strlen (s1)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

La funzione

strcmp(s1s2)

puograve essere utilizzata per effettuare comparazioni sul contenuto di due stringhe In particolare tale funzione

Restituisce un valore positivo se vale s1gts2

Restituisce un valore negativo se vale s1lts2

Restituisce 0 se s1 ed s2 sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

Per tenere conto mnemonicamente di tali valori basta pensare al confronto come ad una sottrazione fra lrsquoaltro ciograve egrave non egrave molto distante da quello che avviene in effetti

Se da s1 si sottrae s2 si avragrave un valore positivo nel caso s1gts2 negativo se s1lts2 e nullo se sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzioni per il trattamento delle stringhe

Nonostante il linguaggio C non possieda un dato di tipo stringa sono disponibili parecchie funzioni specifiche per il trattamento di questrsquoultime

gets e puts

strcpy

strcat strlen e strcmp

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzioni ldquogetsrdquo e ldquoputsrdquo

Le funzioni gets e puts sono funzioni specializzate nellinput e output di una stringa Il programma seguente riceve in input una stringa e subito dopo la rimanda in output

Notare che in queste istruzioni si fa riferimento alla stringa nel suo complesso e quindi viene utilizzato il nome

include ltstdiohgt

main()

char s[80] dichiara la stringa

gets(s) riceve linput

puts(s) fornisce loutput

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Altre funzioni per il trattamento delle stringhesono disponibili per usi particolari a patto chesi includa nel programma la libreria delle

funzioni ldquostringrdquo mediante la seguente istruzione

include ltstringhgt

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcpyrdquo

Questa funzione copia una stringa in unaltra

Puograve essere utilizzata per esempio per assegnare un valore a una stringa La sua sintassi egrave

strcpy(s1s2)

Si puograve immaginare che tale funzione equivale come effetto allassegnamento nelle variabili di altro tipo (in altri termini egrave come se si scrivesse s1=s2) assegna cioegrave alla stringa s1 il valore contenuto in s2

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcatrdquo

La funzione

strcat(s1s2)

concatena la stringa s2 alla fine della stringa s1

strcpy(s1buon) stringa specificata

in s1

strcpy(s2giorno) lo stesso per s2

strcat(s1s2) s1 conterragrave buongiorno

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione rdquo strlen rdquo

La funzione

strlen(s1)

restituisce un valore numerico che rappresenta la lunghezza della stringa s1

Es a=strlen (s1)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

La funzione

strcmp(s1s2)

puograve essere utilizzata per effettuare comparazioni sul contenuto di due stringhe In particolare tale funzione

Restituisce un valore positivo se vale s1gts2

Restituisce un valore negativo se vale s1lts2

Restituisce 0 se s1 ed s2 sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

Per tenere conto mnemonicamente di tali valori basta pensare al confronto come ad una sottrazione fra lrsquoaltro ciograve egrave non egrave molto distante da quello che avviene in effetti

Se da s1 si sottrae s2 si avragrave un valore positivo nel caso s1gts2 negativo se s1lts2 e nullo se sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzioni ldquogetsrdquo e ldquoputsrdquo

Le funzioni gets e puts sono funzioni specializzate nellinput e output di una stringa Il programma seguente riceve in input una stringa e subito dopo la rimanda in output

Notare che in queste istruzioni si fa riferimento alla stringa nel suo complesso e quindi viene utilizzato il nome

include ltstdiohgt

main()

char s[80] dichiara la stringa

gets(s) riceve linput

puts(s) fornisce loutput

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Altre funzioni per il trattamento delle stringhesono disponibili per usi particolari a patto chesi includa nel programma la libreria delle

funzioni ldquostringrdquo mediante la seguente istruzione

include ltstringhgt

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcpyrdquo

Questa funzione copia una stringa in unaltra

Puograve essere utilizzata per esempio per assegnare un valore a una stringa La sua sintassi egrave

strcpy(s1s2)

Si puograve immaginare che tale funzione equivale come effetto allassegnamento nelle variabili di altro tipo (in altri termini egrave come se si scrivesse s1=s2) assegna cioegrave alla stringa s1 il valore contenuto in s2

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcatrdquo

La funzione

strcat(s1s2)

concatena la stringa s2 alla fine della stringa s1

strcpy(s1buon) stringa specificata

in s1

strcpy(s2giorno) lo stesso per s2

strcat(s1s2) s1 conterragrave buongiorno

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione rdquo strlen rdquo

La funzione

strlen(s1)

restituisce un valore numerico che rappresenta la lunghezza della stringa s1

Es a=strlen (s1)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

La funzione

strcmp(s1s2)

puograve essere utilizzata per effettuare comparazioni sul contenuto di due stringhe In particolare tale funzione

Restituisce un valore positivo se vale s1gts2

Restituisce un valore negativo se vale s1lts2

Restituisce 0 se s1 ed s2 sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

Per tenere conto mnemonicamente di tali valori basta pensare al confronto come ad una sottrazione fra lrsquoaltro ciograve egrave non egrave molto distante da quello che avviene in effetti

Se da s1 si sottrae s2 si avragrave un valore positivo nel caso s1gts2 negativo se s1lts2 e nullo se sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Altre funzioni per il trattamento delle stringhesono disponibili per usi particolari a patto chesi includa nel programma la libreria delle

funzioni ldquostringrdquo mediante la seguente istruzione

include ltstringhgt

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcpyrdquo

Questa funzione copia una stringa in unaltra

Puograve essere utilizzata per esempio per assegnare un valore a una stringa La sua sintassi egrave

strcpy(s1s2)

Si puograve immaginare che tale funzione equivale come effetto allassegnamento nelle variabili di altro tipo (in altri termini egrave come se si scrivesse s1=s2) assegna cioegrave alla stringa s1 il valore contenuto in s2

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcatrdquo

La funzione

strcat(s1s2)

concatena la stringa s2 alla fine della stringa s1

strcpy(s1buon) stringa specificata

in s1

strcpy(s2giorno) lo stesso per s2

strcat(s1s2) s1 conterragrave buongiorno

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione rdquo strlen rdquo

La funzione

strlen(s1)

restituisce un valore numerico che rappresenta la lunghezza della stringa s1

Es a=strlen (s1)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

La funzione

strcmp(s1s2)

puograve essere utilizzata per effettuare comparazioni sul contenuto di due stringhe In particolare tale funzione

Restituisce un valore positivo se vale s1gts2

Restituisce un valore negativo se vale s1lts2

Restituisce 0 se s1 ed s2 sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

Per tenere conto mnemonicamente di tali valori basta pensare al confronto come ad una sottrazione fra lrsquoaltro ciograve egrave non egrave molto distante da quello che avviene in effetti

Se da s1 si sottrae s2 si avragrave un valore positivo nel caso s1gts2 negativo se s1lts2 e nullo se sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcpyrdquo

Questa funzione copia una stringa in unaltra

Puograve essere utilizzata per esempio per assegnare un valore a una stringa La sua sintassi egrave

strcpy(s1s2)

Si puograve immaginare che tale funzione equivale come effetto allassegnamento nelle variabili di altro tipo (in altri termini egrave come se si scrivesse s1=s2) assegna cioegrave alla stringa s1 il valore contenuto in s2

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcatrdquo

La funzione

strcat(s1s2)

concatena la stringa s2 alla fine della stringa s1

strcpy(s1buon) stringa specificata

in s1

strcpy(s2giorno) lo stesso per s2

strcat(s1s2) s1 conterragrave buongiorno

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione rdquo strlen rdquo

La funzione

strlen(s1)

restituisce un valore numerico che rappresenta la lunghezza della stringa s1

Es a=strlen (s1)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

La funzione

strcmp(s1s2)

puograve essere utilizzata per effettuare comparazioni sul contenuto di due stringhe In particolare tale funzione

Restituisce un valore positivo se vale s1gts2

Restituisce un valore negativo se vale s1lts2

Restituisce 0 se s1 ed s2 sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

Per tenere conto mnemonicamente di tali valori basta pensare al confronto come ad una sottrazione fra lrsquoaltro ciograve egrave non egrave molto distante da quello che avviene in effetti

Se da s1 si sottrae s2 si avragrave un valore positivo nel caso s1gts2 negativo se s1lts2 e nullo se sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcatrdquo

La funzione

strcat(s1s2)

concatena la stringa s2 alla fine della stringa s1

strcpy(s1buon) stringa specificata

in s1

strcpy(s2giorno) lo stesso per s2

strcat(s1s2) s1 conterragrave buongiorno

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione rdquo strlen rdquo

La funzione

strlen(s1)

restituisce un valore numerico che rappresenta la lunghezza della stringa s1

Es a=strlen (s1)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

La funzione

strcmp(s1s2)

puograve essere utilizzata per effettuare comparazioni sul contenuto di due stringhe In particolare tale funzione

Restituisce un valore positivo se vale s1gts2

Restituisce un valore negativo se vale s1lts2

Restituisce 0 se s1 ed s2 sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

Per tenere conto mnemonicamente di tali valori basta pensare al confronto come ad una sottrazione fra lrsquoaltro ciograve egrave non egrave molto distante da quello che avviene in effetti

Se da s1 si sottrae s2 si avragrave un valore positivo nel caso s1gts2 negativo se s1lts2 e nullo se sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione rdquo strlen rdquo

La funzione

strlen(s1)

restituisce un valore numerico che rappresenta la lunghezza della stringa s1

Es a=strlen (s1)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

La funzione

strcmp(s1s2)

puograve essere utilizzata per effettuare comparazioni sul contenuto di due stringhe In particolare tale funzione

Restituisce un valore positivo se vale s1gts2

Restituisce un valore negativo se vale s1lts2

Restituisce 0 se s1 ed s2 sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

Per tenere conto mnemonicamente di tali valori basta pensare al confronto come ad una sottrazione fra lrsquoaltro ciograve egrave non egrave molto distante da quello che avviene in effetti

Se da s1 si sottrae s2 si avragrave un valore positivo nel caso s1gts2 negativo se s1lts2 e nullo se sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

La funzione

strcmp(s1s2)

puograve essere utilizzata per effettuare comparazioni sul contenuto di due stringhe In particolare tale funzione

Restituisce un valore positivo se vale s1gts2

Restituisce un valore negativo se vale s1lts2

Restituisce 0 se s1 ed s2 sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

Per tenere conto mnemonicamente di tali valori basta pensare al confronto come ad una sottrazione fra lrsquoaltro ciograve egrave non egrave molto distante da quello che avviene in effetti

Se da s1 si sottrae s2 si avragrave un valore positivo nel caso s1gts2 negativo se s1lts2 e nullo se sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Funzione ldquostrcmprdquo

Per tenere conto mnemonicamente di tali valori basta pensare al confronto come ad una sottrazione fra lrsquoaltro ciograve egrave non egrave molto distante da quello che avviene in effetti

Se da s1 si sottrae s2 si avragrave un valore positivo nel caso s1gts2 negativo se s1lts2 e nullo se sono uguali

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempioinclude ltstdiohgt

include ltstringhgt

main()

char S1[10]S2[10] dichiara le

stringhe

gets (S1)

gets (S2)

if (strcmp (S1S2)==0)

printf(n Le parole sono uguali )

else

printf(n Le parole sono diverse

)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Array di stringhe

Una applicazione interessante delle matrici egrave lrsquoarray di stringhe

La stringa egrave un array di caratteri e quindi potremmo dire che un array di stringhe egrave un array di array di caratteri

Per chiarire la gestione di questo tipo di array esaminiamo un programma che si occupa di cercare delle parole in un vocabolario e ci dica per ognuna se egrave contenuta nel vocabolario stesso

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Cerca parole in un vocabolario

include ltstdiohgt

include ltstringhgt 1

main()

char vocab[10][20] parcerc[20] 2

int itrovata

Acquisisce parole da inserire nel vocabolario

for (i=0ilt=9i++)

printf(nParola d i)

gets(vocab[i]) 3

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

Acquisisce la parola da cercare

printf(nnParola da cercare (Invio per finire)

)

gets(parcerc)

while (strcmp(parcerc)) 4

Cerca la parola

trovata=0 5

for (i=0ilt=9i++)

if (strcmp(parcercvocab[i])) 6

trovata=1 7

break 8

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Programma esempio

if (trovata) 9

printf(nParola trovata)

else

printf(nParola non trovata)

Prossima parola da cercare

printf(nnParola da cercare (Invio

per finire) )

gets(parcerc)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

include ltstringhgt 1

La dichiarazione della riga 1

permette lrsquoutilizzo allrsquointerno del programma delle funzioni per il trattamento delle stringhe

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar vocab[10][20] parcerc[20] 2

Nella riga 2 viene dichiarato lrsquoarray di caratteri vocab[10][20] Il nostro vocabolario conterragrave quindi un massimo di 10 parole ognuna composta di un massimo di 20 caratteri La prima parola egrave contenuta in vocab[0] e con vocab[2][7] qualora dovesse interessare si individuerebbe lrsquoottavo carattere della terza parola del vocabolario Ogni riga della tabella conterragrave una parola e in ogni colonna ci sono i caratteri che compongono le parole Lrsquoarray parcerc[20] serviragrave per contenere la parola da cercare

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione gets(vocab[i]) 3

Nella riga 3 si acquisiscono le parole da inserire nel vocabolario la prima volta lrsquoistruzione si leggeragrave gets(vocab[0]) quindi gets(vocab[1]) e infine gets(vocab[9]) in relazione ai diversi valori assunti dal contatore i

Lrsquouso di un solo indice dipende dal fatto che con la gets si acquisisce una stringa e quindi nel nostro caso una intera riga della matrice

Se avessimo voluto acquisire le stringhe un carattere per volta si sarebbero dovuti gestire due cicli uno annidato nellrsquoaltro contenenti lrsquoistruzione scanf(campvocab[i][j])

Alla fine avremmo dovuto aggiungere il carattere null

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

while (strcmp(parcerc)) 4

Nella riga 4 si gestisce la condizione di uscita dal ciclo

La stringa ricevuta dallrsquoinput viene comparata con la stringa vuota (due doppi apici consecutivi) se alla richiesta di input della stringa da cercare si risponde premendo solamente il tasto Invio viene acquisita una stringa contenente solo il carattere terminatore null

Ciograve rende falsa la condizione e quindi il ciclo ha termine (strcmp in questo caso restituisce 0)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=0 5

La variabile trovata che viene azzerata nella riga 5

registreragrave lrsquoeventuale ritrovamento della stringa allrsquointerno del vocabolario

Il valore assegnato non ha il senso di un valore numerico a tutti gli effetti ma il senso di un valore logico (0 = falso un valore non nullo=vero)

Una variabile usata in questo modo viene chiamata solitamente variabile logica switch o flag

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (strcmp(parcercvocab[i])) 6

Nella 6 si confronta la parola da

cercare via via con le parole contenute

nel vocabolario

Lrsquoequivalenza delle due stringhe quella

da cercare e la parola del vocabolario

esaminata rende vera la condizione

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

trovata=1 7

break 8

In questo caso riga 7 si rende vera

la variabile trovata assegnandole un

valore non nullo e con la break della

riga 8 si forza lrsquouscita dal ciclo

poicheacute egrave inutile continuare a

confrontare la parola cercata con il

resto delle parole del vocabolario la

ricerca viene sospesa

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

if (trovata) 9

Nella riga 9 si esegue un test sul flag trovata se egrave vero (cioegrave egrave stata eseguita lrsquoistruzione della riga 7)

la parola egrave stata trovata se egrave falso (egrave rimasto inalterato il valore assegnato nella istruzione della riga 5) la ricerca ha avuto esito negativo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe e i puntatori

Un metodo comunemente utilizzato per dichiarare e manipolare stringhe nei programmi egrave offerto dai puntatori

Come si vede nel programma dellesempio seguente che visualizza Ciao Ciao e porta a capo il cursore

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

include ltstdiohgt

char string = Ciao

void main(void)

printf(string)

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionechar string = Ciao

La dichiarazione di string puograve apparire a prima vista anomala

Si tratta infatti a tutti gli effetti della dichiarazione di un puntatore e la stranezza consiste nel fatto che a questo non egrave assegnato un indirizzo di memoria come ci si potrebbe aspettare bensigrave una costante stringa

Ma egrave proprio questo lartificio che consente di gestire le stringhe con normali puntatori a carattere il compilatore in realtagrave assegna a string puntatore a 16 bit lindirizzo della costante Ciao

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneDunque la word occupata da string non contiene la parola Ciao ma i 16 bit che esprimono la parte offset del suo indirizzo

A sua volta Ciao occupa 5 byte di memoria Proprio 5 non si tratta di un errore di stampa i 4 byte necessari a memorizzare i 4 caratteri che compongono la parola piugrave un byte nel quale il compilatore memorizza il valore binario 0 detto terminatore di stringa o null terminator

In C tutte le stringhe sono chiuse da un null terminator ed occupano perciograve un byte in piugrave del numero di caratteri stampabili che le compongono

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(string)

La prima chiamata a printf() passa quale argomento proprio string dunque la stringa parametro indispensabile di printf() non deve essere necessariamente una stringa di formato quando lunica cosa da visualizzare sia proprio una stringa Lo egrave perograve quando devono essere visualizzati caratteri o numeri o stringhe formattate in un modo particolare come avviene nella seconda chiamata

printf( s nstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Per visualizzare una stringa con printf() occore

fornirne lindirizzo che nel nostro caso egrave il contenuto del puntatore string

Se string punta alla stringa Ciao che cosa restituisce lespressione string

La tentazione di rispondere Ciao egrave forte ma se cosigrave

fosse percheacute per visualizzare la parola occorre passare a printf() string e non string

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il problema non si poneva con gli esempi precedenti percheacute tutti i puntatori esaminati indirizzavano un unico dato di un certo tipo

Con le dichiarazioni

float numero = 125

float numPtr = ampnumero

si definisce il puntatore numPtr e lo si inizializza in modo che contenga lindirizzo della variabile numero la quale in fondo proprio come string occupa piugrave di un byte In questo caso perograve i 4 byte di numerocontengono un dato unitariamente considerato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

OsservazioniIn altre parole nessuno dei 4 byte che la compongono ha significato in seacute e per seacute

Con riferimento a string al contrario ogni byte egrave un dato a seacute stante cioegrave un dato di tipo char bisogna allora precisare che un puntatore indirizza sempre il primo byte di tutti quelli che compongono il tipo di dato considerato se questi sono piugrave duno

Se ne ricava che string contiene in realtagrave lindirizzo del primo carattere di Ciao cioegrave la C

Allora string non puograve che restituire proprio quella come si puograve facilmente verificare con la seguente chiamata a printf()

printf(c egrave il primo caratterenstring)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Le stringhe come sequenze di caratteri

Le stringhe sono per il compilatore C semplici sequenze di char la stringa del nostro esempio char string = Ciao

inizia con il char che si trova allindirizzo contenuto in string (la C) e termina con il primo byte nullo incontrato ad un indirizzo uguale o superiore a quello del primo carattere (nellrsquoesempio il byte che segue immediatamente la o)

Per accedere ai caratteri che seguono il primo egrave sufficiente incrementare il puntatore o comunque sommare ad esso una opportuna quantitagrave (che rappresenta loffset cioegrave lo spostamento dallinizio della stringa stessa)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

Lesempio si basa sullaritmetica dei puntatori cioegrave sulla possibilitagrave di accedere ai dati memorizzati ad un certo offset rispetto ad un indirizzo sommandovi algebricamente numeri interi

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizionewhile((string+i) = 0)

printf(cn(string+i))

++i

Il ciclo visualizza la stringa Ciao in senso verticale

Infatti listruzione while esegue le istruzioni comprese tra le parentesi graffe fincheacute la condizione espressa tra le parentesi tonde egrave vera (se questa egrave falsa la prima volta il ciclo non viene mai eseguito) in questo caso la printf() egrave eseguita fincheacute il byte che si trova allindirizzo contenuto in string aumentato di i unitagrave egrave diverso da 0 cioegrave fincheacute non viene incontrato il null terminator

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Descrizione

printf(cn(string+i))

La printf() visualizza il byte a quello stesso indirizzo

e va a capo

Il valore di i egrave inizialmente 0 pertanto nella prima iterazione lindirizzo espresso da string non egrave modificato ma ad ogni loop i egrave incrementato di 1

(tale egrave il significato delloperatore ++) pertanto ad ogni successiva iterazione lespressione string+i

restituisce lindirizzo del byte successivo a quello appena visualizzato

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

DescrizioneAl termine i contiene il valore 4 che egrave anche la

lunghezza della stringa questa egrave infatti convenzionalmente pari al numero dei caratteri stampabili che compongono la stringa stessa il null terminator non viene considerato

int i = 0

while((string+i) = 0)

printf(cn(string+i))

++i

In altre parole la lunghezza di una stringa egrave inferiore di 1

al numero di byte che essa occupa effettivamente in memoria

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Lunghezza di una stringa

La lunghezza di una stringa puograve quindi essere calcolata cosigrave

unsigned i = 0

while((string+i)) ++i

La condizione tra parentesi egrave implicita non viene specificato alcun confronto

In casi come questo il compilatore assume che il confronto vada effettuato con il valore 0 che egrave proprio quel che fa al nostro caso

Inoltre dato che il ciclo si compone di una sola riga (lautoincremento di i) le graffe non sono necessarie

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazione

Quando ad una funzione viene passata una costante stringa come in

printf(Ciaon)

il compilatore astutamente memorizza la

costante e ne passa lindirizzo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Esempio modifica di una stringa

char string = Rosson

Void main(void)

printf(string)

(string+3) = p

printf(string)

Il programma dellesempio visualizza dapprima la parola Rosso e poi Rospo

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

Il valore di string non egrave mutato esso continua a puntare alla medesima locazione di memoria ma egrave mutato il contenuto del byte che si trova ad un offset di 3 rispetto a quellindirizzo

Dal momento che lindirezione di un puntatore a carattere restituisce un carattere nellassegnazione della lettera p egrave necessario esprimere questultima come un char e pertanto tra apici (e non tra virgolette)

La variabile string non a casp egrave dichiarata allesterno di main()

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come troncare una stringa

Per troncare una stringa basta inserire un NULLdove occorre

(string+2) = NULL

A questo punto una chiamata a printf() visualizzerebbe la parola Ro

NULL egrave una costante manifesta definita in STDIOH e rappresenta lo zero binario infatti la riga di codice precedente potrebbe essere scritta cosigrave

(string+2) = 0

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Come allungare una stringaSe si sovrascrive il NULL con un carattere la stringa si allunga sino al successivo NULL

Occorre fare alcune considerazioni

in primo luogo tale operazione ha senso di solito solo nel caso di concatenamento di stringhe (quando cioegrave si desidera accodare una stringa ad unaltra per produrne una sola piugrave lunga)

In secondo luogo se i byte successivi al NULL sono occupati da altri dati questi vengono perduti sovrascritti dai caratteri concatenati alla stringa leffetto puograve essere disastroso

Abbiamo visto che esiste una funzione di libreria concepita appositamente per concatenare le stringhe la strcat() che richiede due stringhe quali parametri Lazione da essa svolta consiste nel copiare i byte che compongono la seconda stringa NULL terminale compreso in coda alla prima stringa sovrascrivendone il NULL terminale

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

Osservazioni

In una dichiarazione come quella di string il

compilatore riserva alla stringa lo spazio strettamente necessario a contenere i caratteri che la compongono piugrave il NULL

E evidente che concatenare a string unaltra

stringa sarebbe un grave errore (peraltro non segnalato dal compilatore percheacute esso lascia il programmatore libero di gestire la memoria come crede se sbaglia peggio per lui)

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

E meglio sottolineare che le librerie standard del C comprendono un gran numero di funzioni (dichiarate in STRINGH) per la manipolazione delle stringhe che effettuano le piugrave svariate operazioni copiare stringhe o parte di esse (strcpy() strncpy()) concatenare stringhe (strcat() strncat()) confrontare stringhe (strcmp() stricmp()) ricercare sottostringhe o caratteri allinterno di stringhe (strstr() strchr() strtok())

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE

Ing Cristian Randieri ndash Lezioni di programmazione in C rdquoLe stringherdquo

FINE