Stringhe. Stringhe costanti. t[0] t[1] t[2] t[3] t[4] s o l e \0. Esempio. char t[5] = { l, u, n, a, \0 }; definisce l array

Documenti analoghi
4 GLI ARRAY E LE STRINGHE

Esercitazione 4. Comandi iterativi for, while, do-while

Definizione di metodi in Java

FILE BINARI FILE BINARI

La rappresentazione delle informazioni

L accesso ai dispositivi esterni (tastiera, monitor, file,...) viene gestito mediante canali di comunicazione.

Bit, Byte, Word e Codifica Dati

Linguaggio C: introduzione

Uso di metodi statici. Walter Didimo

Variabili. Unità 2. Domenico Daniele Bloisi. Corso di Programmazione e Metodi Numerici Ingegneria Aerospaziale BAER

La gestione dei caratteri in C

Problema: calcolare il massimo tra K numeri

Somma di numeri floating point. Algoritmi di moltiplicazione e divisione per numeri interi

Il generatore di numeri casuali

Input/output in C e in C++

UD4 - MATLAB. M-file. Efficienza degli algoritmi. Formati d uscita

Unità Didattica 3 Linguaggio C. Generalità sulle Funzioni. Variabili locali e globali. Passaggio di parametri per valore.

Files in C++ Fondamenti di Informatica. R. Basili. a.a

Array multidimensionali e stringhe

2) FILE BINARI: è una sequenza di byte avente una corrispondenza uno a uno con la sequenza ricevuta dal dispositivo esterno.

Mini-Corso di Informatica

Esercitazione 3. Espressioni booleane I comandi if-else e while

I file Laboratorio di Linguaggi di Programmazione a.a. 2001/2002

STRINGHE: ARRAY DI CARATTERI! a p e \0

ESAME DI FONDAMENTI DI INFORMATICA I ESAME DI ELEMENTI DI INFORMATICA. 28 Gennaio 1999 PROVA SCRITTA

Informatica Teorica. Macchine a registri

LEZIONE 4. { x + y + z = 1 x y + 2z = 3

APPELLO SCRITTO DI PROGRAMMAZIONE 1 CORSO DI LAUREA IN MATEMATICA UNIVERSITÀ DEGLI STUDI DI MILANO VI.2014

Stringhe di caratteri

Introduzione al C. Introduzione. Linguaggio ad alto livello. Struttura di un programma C

ESAME DI FONDAMENTI DI INFORMATICA I ESAME DI ELEMENTI DI INFORMATICA. 28 Gennaio 1999 PROVA SCRITTA

Lezione 4. Sommario. L artimetica binaria: I numeri relativi e frazionari. I numeri relativi I numeri frazionari

Laboratorio di Programmazione: Linguaggio C Lezione 9 del 27 novembre 2013

Appunti di informatica. Lezione 4 anno accademico Mario Verdicchio

PROGRAMMAZIONE STRUTTURATA

CARATTERI E STRINGHE Caratteri e stringhe Funzioni della libreria standard I/O Funzioni della libreria di gestione delle stringhe

Laboratorio di Architettura degli Elaboratori

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 1

giapresente( ) leggi( ) char * strstr(char * cs, char * ct) NULL

Esercitazione 5. Procedure e Funzioni Il comando condizionale: switch

LP1 Lezione 13: i File in C. Maurizio Tucci

La codifica. dell informazione

Macchine RAM. API a.a. 2013/2014 Gennaio 27, 2014 Flavio Mutti, PhD

Gestione dei file. Linguaggio ANSI C Input/Output - 13

Fondamenti VBA. Che cos è VBA

La Rappresentazione dell Informazione

La programmazione nel linguaggio C

Compitino di Laboratorio di Informatica CdL in Matematica 13/11/2007 Teoria Compito A

Diagrammi a blocchi 1

IL CONCETTO DI FILE. È illecito operare oltre la fine del file.

Informatica d ufficio

Esercizi per il recupero del debito formativo:

Gestione di files Motivazioni

La segreteria didattica dovrà eseguire semplici operazioni per effettuare lo scrutinio:

Come utilizzare i riferimenti assoluti e relativi in Microsoft Excel

FILE BINARI. I file di testo non sono indispensabili: sono semplicemente comodi 1

Codifica dei Numeri. Informatica ICA (LC) 12 Novembre 2015 Giacomo Boracchi

Esame Informatica Generale 13/04/2016 Tema A

7 2 =7 2=3,5. Casi particolari. Definizione. propria se < impropria se > e non è multiplo di b. apparente se è un multiplo di. Esempi.

float somma_float(float a, float b) int get_ascii(char c)

Gli array. Gli array. Gli array. Classi di memorizzazione per array. Inizializzazione esplicita degli array. Array e puntatori

Introduzione al C. Stream e disk file

INDICE. Vista Libretto Livello Digitale 2. Importazione di dati da strumento 3. Inserisci File Vari 5. Compensazione Quote 5.

Risoluzione di problemi ingegneristici con Excel

Introduzione a Visual Basic Lezione 2 Cicli e anomalie

Istruzioni iterative. Istruzioni iterative

Codice Gray. (versione Marzo 2007)

1.2d: La codifica Digitale dei caratteri

DOTT. ING. LEONARDO RIGUTINI DIPARTIMENTO INGEGNERIA DELL INFORMAZIONE UNIVERSITÀ DI SIENA VIA ROMA SIENA UFF

Sistemi Operativi Anno Accademico 2011/2012. Segnali: Interrupt software per la gestione di eventi asincroni

Rappresentazioni numeriche

APPUNTI DI MATEMATICA ALGEBRA \ CALCOLO LETTERALE \ MONOMI (1)

Introduzione alle macchine a stati (non definitivo)

Architettura degli elaboratori Docente:

Fondamenti di Informatica. Algoritmi di Ricerca e di Ordinamento

Linguaggio C++ 8. Matrici

Note sull implementazione in virgola fissa di filtri numerici

Manipolazioni elementari di flussi di testo strutturati

Esercizi svolti. risolvere, se possibile, l equazione xa + B = O, essendo x un incognita reale

Linguaggio Macchina. Linguaggio Macchina. Linguaggio Macchina. Linguaggio Macchina ADD A,B ISTRUZIONE SUCCESSIVA

Programmazione. Cognome... Nome... Matricola... Prova scritta del 11 luglio 2014

Individuazione di sottoproblemi

Algoritmi. Pagina 1 di 5

LA CODIFICA DELL INFORMAZIONE. Introduzione ai sistemi informatici D. Sciuto, G. Buonanno, L. Mari, McGraw-Hill Cap.2

= < < < < < Matematica 1

Allocazione Dinamica della Memoria

Programmazione. Cognome... Nome... Matricola... Prova scritta del 22 settembre Negli esercizi proposti si utilizzano le seguenti classi:

Strutture Dinamiche. Fondamenti di Informatica

Modulo 1: Le I.C.T. UD 1.2d: La codifica Digitale dei caratteri

Codifica dell Informazione

EXCEL: FORMATTAZIONE E FORMULE

Compilazione on-line del Piano di Studio

Introduzione alla programmazione. Walter Didimo

Procedura operativa per la gestione della funzione di formazione classi prime

Un grafico utilizza i valori contenuti in un foglio di lavoro per creare una rappresentazione grafica delle relazioni esistenti tra loro;

Gli Operatori. Università degli Studi di Brescia

Sommario. Tabelle ad indirizzamento diretto e hash Funzioni Hash

Esame Laboratorio di Sistemi Operativi Cognome Nome Mat.

TEOREMA DEL RESTO E REGOLA DI RUFFINI

Numeri frazionari. sistema posizionale. due modi: virgola fissa virgola mobile. posizionale, decimale

Transcript:

Stringhe Esempio char t[5] = { l, u, n, a,; definisce l array In ANSI C una stringa è una successione di caratteri terminata dal carattere (carattere nullo, il cui valore è 0, da non confondere con il carattere 0 il cui valore è 48). I caratteri che formano la stringa (compreso il carattere di fine stringa) devono essere memorizzati in un array di char. Una stringa è quindi rappresentata in memoria come una sequenza di byte (dimensione del tipo char) che termina con 0. t[0] t[1] t[2] t[3] t[4] l u n a dove l è la costante intera 108, u è la costante 117, ecc.; il valore di t[4] è 0. L array t[] rappresenta la stringa "luna". 1 2 Definizioni equivalenti: char t[5] = "luna"; char t[10] = "luna"; - Nella prima definizione l array t[] contiene 5 elementi, che è la minima dimensione che un array deve avere per contenere la parola "luna" (4 caratteri + carattere fine stringa). - Nel secondo caso, t[] contiene 5 elementi in più del necessario, il cui valore iniziale non è definito. Tuttavia, anche in questo caso t[] rappresenta la stringa "luna". Stringhe costanti Una stringa costante è scritta tra doppi apici. Il tipo di una stringa costante è char*. Il valore di una stringa costante è l indirizzo al primo elemento dell array che rappresenta la stringa stessa. Esempio La stringa costante "sole" è rappresentata dall array Nota Le stringhe non hanno una rappresentazione astratta, ma sono array di caratteri su cui sono ammesse tutte le operazioni per gli array. È compito del programmatore assicurarsi che le convenzioni sulla rappresentazione di stringhe siano rispettate. s o l e 3 4

Si possono usare sulla stringa le notazioni usate per array e puntatori. Quindi, le espressioni Osservazioni "sole" "sole" + 1 "sole" + 4 equivalenti a &"sole"[0] &"sole"[1] &"sole"[4] hanno tipo char* e il loro valore è dato dall indirizzo delle locazioni di memoria contenenti rispettivamente i caratteri s, o e. Le espressioni *"sole" *("sole" + 1) *("sole" + 4) Non confondere 1 (costante di tipo int e valore 1), 1 (costante di tipo int e valore 49) e "1" (stringa rappresentata da un array contenente i caratteri 1 e ). Non è possibile modificare le stringhe costanti (anche se alcuni compilatori lo permettono!); è possibile invece modificare le stringhe non costanti (come avviene per gli array). equivalenti a "sole"[0] "sole"[1] "sole"[4] hanno tipo char e valore rispettivamente s (=115), o (=111) e (=0). 5 6 La dichiarazione char t[n]= "luna"; dove si assume N 5, definisce un array di char contenente la stringa "luna" (se N 6, il valore nelle locazioni di memoria t[5], t[6],...t[n-1] non è definito e dipende dal sistema). È invece sbagliato fare char t[n]; t = "luna"; Infatti, l assegnamento è interpretato come: Assegna a t il valore di "luna" (= indirizzo dell array che rappresenta tale stringa). Non è possibile fare ciò in quanto il nome di un array è una costante (il cui valore è l indirizzo al primo elemento dell array), quindi non può essere modificato. Il codice non è compilato. È invece possibile fare: char *t; t = "luna"; Il valore di t è ora l indirizzo dell array contente la stringa "luna". t L istruzione printf("%c", *t); l u n a stampa su standard output il carattere l. Poiché t è una variabile di tipo puntatore (e non il nome di un array!), il suo valore può essere modificato. 7 8

Dopo l assegnamento t = t + 2; si ha: t l u n a Questa volta l istruzione printf("%c", *t) stampa su standard output il carattere n. Non è invece possibile fare *t = c ; per ottenere la stringa "luca", in quanto "luna" è una stringa costante e non può essere modificata (il programma è compilato ugualmente, ma si hanno poi problemi in esecuzione). Funzioni su stringhe Lettura di una stringa Scrivere una funzione read() che legge una stringa da standard input in un array di char passato come parametro, saltando gli eventuali caratteri di spaziatura iniziali (spazi, a capo, ecc.). La funzione deve restituire 1 se la lettura è terminata con successo, EOF se è stato letto il carattere end-of-file. Usare esclusivamente getchar() per leggere i caratteri presenti su standard input e isspace() per riconoscere i caratteri di spaziatura: isspace() restituisce un valore diverso da 0 (il cui valore non è stabilito dall ANSI C) se il carattere passato come argomento è un carattere di spaziatura, 0 altrimenti. Assumere che l array passato come parametro contenga sufficiente spazio per contenere la stringa letta. 9 10 Codice di read() Nota Quando una funzione deve memorizzare una stringa in un array a[] passato come parametro, è consuetudine assumere che a[] contenga spazio sufficiente per memorizzare la stringa (questa assunzione viene fatta anche nelle funzioni su stringhe delle librerie ANSI C). È compito del chiamante assicurarsi che l assunzione sia rispettata. In generale questo tipo di assunzione va fatta quando una funzione memorizza dei dati in un array passato come parametro. Ad esempio, in void copy(int to[], int from[], int n) (copia n elementi dall array from[] all array to[]) è necessario assumere che to[] abbia almeno n elementi. L intestazione della funzione può essere scritta in una delle due forme equivalenti: int read(char word[]) La funzione deve compiere le seguenti operazioni: int read(char *word) 1. Salta gli spazi iniziali Legge un carattere alla volta da standard input e termina quando il carattere letto è EOF oppure è diverso da un carattere di spaziatura. Se l ultimo carattere letto è EOF, la funzione termina restituendo EOF. 11 12

while( (c=getchar())!= EOF && isspace(c) ); /* all uscita dal ciclo, c vale EOF oppure c e il primo carattere della stringa */ if(c == EOF) return EOF; Quando viene valutata l espressione di assegnamento c = getchar() viene chiamata getchar(), il valore restituito è assegnato alla variabile c e il valore dell intera espressione è dato dal valore di c. Quindi, la condizione in while è verificata se e solo se il carattere letto da getchar() è diverso da EOF ed è un carattere di spaziatura. 2. Lettura della parola Vengono letti da standard input un carattere per volta, terminando quando si incontra end-of-file oppure un carattere di spaziatura. I caratteri letti i sono inseriti in word[]. /* c contiene il primo carattere della stringa in input */ k = 0; while(c!=eof &&!isspace(c)){ word[k++] = c; /* equivale a: word[k] = c; k++; */ c = getchar(); /* all uscita dal ciclo, c vale EOF oppure c e un carattere di spaziatura */ 13 14 3. Inserimento marcatore di fine stringa All uscita del ciclo while, sono stati letti tutti i caratteri della parola e l ultimo carattere della parola è in w[k-1]. Occorre inserire il carattere di fine stringa in word[k] word[k] = ; return 1; Si noti che l ultimo assegnamento è equivalente a word[k] = 0; ma è preferibile usare la prima forma per rendere il codice più leggibile. Esempio Supponiamo di eseguire le linee di codice char w[10]; e che lo standard input contenga elefante cane 15

Dopo la prima chiamata a read(), l array w[] contiene: w[0] w[1] w[2] w[3] w[4] w[5] w[6] w[7] w[8] w[9] L ultimo carattere della parola è in w[7] e w[8] contiene il carattere di fine stringa. e l e f a n t e? Dopo la seconda chiamata a read(), l array w[] contiene: w[0] c w[1] a w[2] n w[3] e w[4] w[5] n w[6] t w[7] e w[8] w[9]? 17 18 Stampa di una stringa Si noti che la parola in w[] termina nella locazione di indirizzo w+3 in quanto w[4] contiene il carattere. L array w[] rappresenta la stringa "cane". Se si esegue l istruzione w[0] = ; l array w[] rappresenta invece la stringa nulla, ossia la stringa non contenente alcun carattere. La stringa nulla è denotata da "". Scrivere una funzione print() che stampa su standard output la stringa passata come parametro (cioè, la stringa rappresentata dall array passato come parametro) e restituisce il numero di caratteri stampati. Usare solo putchar(). Codice di print() A differenza delle funzioni sugli array viste prima, non è necessario passare come parametro la lunghezza della stringa. Infatti, per le convenzioni sulla rappresentazione di stringhe, la parola termina quando si incontra il carattere. 19 20

int print(char word[]){ int k; for(k=0 ; word[k]!= ; k++) putchar(word[k]); // putchar(*(word+k)); return k; In forma più compatta: int print(char word[]){ int k; for(k=0 ; word[k]!= ; putchar(word[k++]) ); return k; Si ricordi che l ultima espressione in un ciclo for viene sempre valutata al termine di ogni iterazione. La valutazione di putchar(word[k++]) avviene eseguendo la chiamata putchar() con argomento word[k], successivamente k viene incrementato di uno. Esempio Le linee di codice char w[10]; print("esempio\n"); print("\n"); w[0] = ; /* # */ print(w+2); print(w+6); avendo su standard input elefante producono come output Esempio elefante cane ne te cane 21 22 Per capire l effetto delle ultime operazioni di stampa, occorre tenere presente che, dopo l istruzione #, l array w[] contiene Pertanto, l istruzione w[0] w[1] w[2] w[3] w[4] w[5] w[6] w[7] w[8] w[9] non produce alcun effetto in quanto w[] rappresenta la stringa nulla. a n e n t e? L istruzione print(w+2); richiede la stampa della stringa contenuta nel sottoarray che inizia in w+2. Tale stringa è data dalla sequenza di caratteri da w[2] fino al prossimo carattere, che è in w[4]. Viene quindi stampato ne Analogamente, l ultima operazione stampa la stringa contenuta nell array w+6 che è te 23 24

Osservazioni 1. Se prima dell ultima operazione di stampa si esegue l istruzione w[8] = a ; cosa succede? In questo caso l array w+6 non rappresenta più una stringa e l esecuzione di read() ha un comportamento impredicibile. Verrano stampati i valori nelle locazioni indirizzo w+6, w+7,... fintanto che tali valori sono diversi da 0. Un possibile output è: tea?????b Y@?????VB 2. Cosa succede se si esegue char w[10]; e la parola letta da standard input è più lunga di 9 caratteri (l array w[] non contiene sufficiente spazio per contenerla)? I primi 10 caratteri della parola vengono memorizzati nelle locazioni di indirizzo w, w+1,..., w+9 che corrispondono a locazioni dell array w[]. I caratteri successivi, vengono posti nelle locazioni aventi indirizzo w+10, w+11,... e il comportamento non è prevedibile. Il compilatore non può rilevare errori di questo tipo perché in C una stringa è un array, su cui sono ammesse tutte le operazioni per gli array. 25 26 I valori in w[] sono 3. Se si esegue char w[10]; avendo su standard input i caratteri a0b \O c cosa contiene l array w[]? La stringa su standard input, saltando gli spazi iniziali, è composta da 8 caratteri. Si noti che il secondo e il sesto carattere corrispondono al carattere 0 (valore 48, da non confondere con l intero 0), il quarto e settimo carattere corrispondono al carattere apice (valore 39). w[0] w[1] w[2] w[3] w[4] w[5] w[6] w[7] w[8] w[9] a 0 B \ 0 c? Se si esegue ora viene stampato a0b \O c 27 28

4. Cosa succede se per rappresentare una stringa si usa una array di int anziché di char? Non è possibile dichiarare un array in questo modo int w[10] = "abc"; in quanto l inizializzazione con stringhe è corretta solo per array di char. In questo caso il codice non è compilato. È invece possibile dichiarare un array di int in questo modo int w[10] = { a, b, c, ; dove w[0] vale a, w[1] vale b, ecc.. Tuttavia, l array non rappresenta la stringa "abc". Infatti, assumendo che il tipo int occupi 4 byte, in memoria si ha la sequenza di byte.. w[0] --> 01100001 /* = 97 = a */ w[1] --> 01100010 /* = 98 = b */ w[2] --> 01100011 /* = 99 = c */ w[3] -->.. 29 30 Per verificarlo, eseguire le seguenti linee di codice che stampano il contenuto dell array w[] byte per byte: char *p; p = (char*) w; // p contiene &w[0]; int dim = sizeof(int) * 10; // numero di byte in w[] for(k=0; k<dim; k++) printf("%o\n", p[k]); // stampa in ottale il valore *(p+k) Si ricordi che p+k, secondo l aritmetica dei puntatori, corrisponde all indirizzo &w[0] + k byte. Poiché in C una stringa è una sequenza di byte terminante con 0, la stringa rappresentata da w[] è "a". Infatti, eseguendo Esercizio Dire cosa succede eseguendo ora le istruzioni w[0] = w[0] + z * pow(2,8); e verificare la risposta scrivendo un opportuno programma. Si tenga presente che pow(2,8) calcola 2 8 e che moltiplicare un numero in notazione binari per 2 k equivale ad aggiungere al numero k zeri (analogamente a quanto avviene moltiplicando un numero in notazione decimale per 10 k ). viene stampato a 31 32

Lettura e stampa con printf() e scanf() Le operazioni di lettura e scrittura descritte prima possono essere effetuate usando scanf() e printf(). Supponiamo che w[] sia un array di char. L istruzione scanf("%s",w); legge una stringa presente da standard input nell array w, saltando gli eventuali caratteri di spaziatura che la precedono. Restituisce: 1 se l operazione di lettura ha successo, EOF se, dopo i caratteri di spaziatura, viene letto il carattere di end-of-file. Si assume che w[] contenga spazio sufficiente per contenere la parola letta (lunghezza della parola più uno per il carattere di fine stringa). L istruzione printf("%s",w); stampa su standard output la stringa rappresentata da w[] e restituisce il numero di caratteri stampati. Le istruzioni print(w+2); print(w+6); sono equivalenti a printf("%s",w); printf("%s",w+2); printf("%s",w+6); È analoga a: 33 34 Osservazioni 2. Il preprocessore non effettua sostituzioni all interno di una stringa. Ad esempio: 1. Il primo argomento di printf() è una stringa; printf() stampa la stringa passata come primo argomento sostituendo gli eventuali caratteri di conversione presenti in essa con il valore dei corrispondenti argomenti, secondo il formato richiesto. Ad esempio, int a = 48; printf("a vale %d, corrispondente al carattere %c.", a, a); stampa a vale 48, corrispondente al carattere 0. #define ESEMPIO sole. printf("esempio \n"); stampa su standard output ESEMPIO Se si vuole stampare sole occorre fare #define ESEMPIO "sole" printf("%s \n", ESEMPIO); /* il preprocessore sostituisce ESEMPIO con "sole" */ 35 36

Esempio di utilizzo della stringa nulla: 3. La stringa "" in cui non ci sono caratteri denota la stringa nulla (rappresentata da un array contenente solamente il carattere ). È diversa dalla stringa " " che è una stringa composta dal carattere spazio (ed è quindi rappresentata da un array di due caratteri). int n; char *p; p = n > 1? "s" : ""; printf("%d element%s.", n, p); Se n vale 5, a p viene assegnata la stringa "s" e viene stampato 5 elements. Se n vale 1, a p viene assegnata la stringa nulla e viene stampato 1 element. Se a p viene assegnata la stringa " " anziché la stringa nulla, viene stampato 1 element. 37 38 Copia di stringhe Definire una funzione strcopy() che copia una stringa s (source) passata come secondo parametro in un array di char t (target) passato come primo parametro. Si assume che t contenga sufficiente spazio per contenere la stringa (ossia, t è l indirizzo di un array di char la cui dimensione è maggiore del numero dei caratteri della stringa in s più uno). Il problema è analogo a quello già visto della copia di vettori. L unica differenza è che in questo caso non è necessario passare come parametro il numero degli elementi da copiare in quanto la funzione è in grado di riconoscere dove termina la stringa in s. void strcopy1 (char t[], char s[]){ /* oppure: void strcopy1 (char *t, char *s) */ int i=0; while ( (t[i] = s[i])!= ) i++; dove t[i] può essere sostituito con *(t+i), s[i] può essere sostituito con *(s+i). Per valutare (t[i] = s[i])!= vengono confrontati i valori delle espressioni a sinistra e a destra di!=. Per l espressione a sinistra, viene prima eseguito l assegnamento t[i]=s[i]; il valore dell espressione di assegnamento è il valore assegnato a t[i]. Si noti che l assegnamento viene effettuato anche quando s[i] contiene, dopo di che l espressione associata a while non è verificata e il ciclo termina. 39 40

La funzione strcopy2() può essere riscritta come Altra versione: void strccopy2 (char *t, char *s){ while ((*t = *s)!= ){ s++; t++; In questo caso i puntatori s e t a ogni iterazione vengono incrementati di uno (nel senso dell aritmetica dei puntatori) e quindi puntano ai successivi elementi degli array passati come parametri. void strcopy2 (char *t, char *s){ while ( (*t++ = *s++)!= ); oppure (ma questa forma è meno leggibile) void strcopy2 (char *t, char *s){ while ( *t++ = *s++ ); in quanto l uscita dal while si ha quando l espressione fra parentesi diventa uguale a 0 (ossia, quando a *t è assegnato ). Esempio 1 void f(){ char *v = "uno"; char w[4]; strcopy2(w,v); 41 42 Supponiamo di eseguire f(). Quando strcopy2() viene eseguita, prima del ciclo while la configurazione della memoria è Dopo il ciclo si ha: strcopy2() t strcopy2() t s s f() v f() v w[0] w[0] w[1] u n u n o w[1] u n o w[2] o w[2] w[3] w[3] 43 44

Esempio 2 char w1[30] = "cavallo"; char w2[50]; strcopy(w2,w1); printf("%s %s", w1, w2); strcopy(w2+1, w1+3); printf("%s %s", w1, w2); strcopy(w1, w1+2); printf("%s %s", w1, w2); dove strcopy() è una delle funzioni per la copia di stringhe viste prima. Eseguendo il codice viene stampato: cavallo cavallo cavallo callo vallo callo Errori da evitare Supponiamo di aver definito char *v = "luna"; char *w; e di voler copiare la stringa "luna" in w. Un tipico errore è quello di fare strcopy(w,v); /* una delle due versioni di prima */ pensando che la funzione strcopy() si preoccupi di creare una nuova stringa e di assegnarla a w. In realtà la funzione si limita a copiare il carattere l in w[0], il carattere u in w[1], ecc. Poiché il valore di w non è definito, il comportamento del codice non è prevedibile. Per funzionare correttamente, occorre assegnare a w (che è una variabile di tipo puntatore) l indirizzo di un array di dimensione opportuna. 45 46 È anche sbagliato fare w = v; Infatti, dopo questa istruzione w e v contengono l indirizzo alla stessa stringa, quindi in w non si ha una copia della stringa "luna", ma si ha un unica stringa condivisa da due variabili. v w l u n a Questo tipo di errori non possono essere segnalati dal compilatore (che si limita solo a controlli di tipo sintattico). Se occorre verificare se due stringhe w1 e w2 sono uguali è sbagliato fare if(w1 == w2) in quanto in questo modo vengono confrontati gli indirizzi delle due stringhe, non i carattari che le compongono. Occorre invece definire una funzione struguale() che confronta le due stringhe carattere per carattere e restituisce 1 se sono uguali, 0 altrimenti e fare if(struguale(w1, w2) == 1) o più semplicemente if(struguale(w1, w2)) % 47 48

La libreria string.h Analogamente, per controllare se w è uguale alla stringa nulla, è sbagliato fare if(w == "") Infatti, in questo modo vengono confrontati i valori di w e di "" (ossia, gli indirizzi dei vettori che contengono la stringa w e la stringa nulla) non il contenuto delle stringhe. Si può fare ad esempio: if(struguale(w, "")) Per gestire le stringhe si possono utilizzare le funzioni di libreria i cui prototipi sono definiti in <string.h>. Ad esempio, la funzione strcopy() prima definita è analoga alla funzione strcpy(). Sono definite funzioni per determinare la lunghezza di una stringa, concatenare stringhe, confrontarle, ecc. Per usarle occorre leggere con attenzione la documentazione riportata sui manuali. 49 50