Trattamento delle STRINGHE in C(++)

Documenti analoghi
Breve riepilogo della puntata precedente:

Introduzione alla programmazione in C

Per scrivere una procedura che non deve restituire nessun valore e deve solo contenere le informazioni per le modalità delle porte e controlli

Cos è una stringa (1) Stringhe. Leggere e scrivere stringhe (1) Cos è una stringa (2) DD Cap. 8 pp KP Cap. 6 pp

Matematica - SMID : Programmazione Febbraio 2009 FOGLIO RISPOSTE

Laboratorio di Programmazione 1. Docente: dr. Damiano Macedonio Lezione 18 31/03/2014

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

Le variabili. Olga Scotti

Funzioni in C. Violetta Lonati

Programmazione C Massimo Callisto De Donato massimo.callisto@unicam.it

Le funzioni in C. I programmi C sono costituiti da definizioni di variabili e funzioni.

Gestione dei File in C

STAMPA UNIONE DI WORD

Le stringhe. Le stringhe

Linguaggio C - Stringhe

void funzioneprova() { int x=2; cout<<"dentro la funzione x="<<x<<endl; }

Corso di Informatica Corso di Laurea in Ingegneria Gestionale a.a Secondo Compitino 17 Dicembre 2005

LABORATORIO DI PROGRAMMAZIONE 1 CORSO DI LAUREA IN MATEMATICA UNIVERSITÀ DEGLI STUDI DI MILANO V Indice

dall argomento argomento della malloc()

Alcune regole di base per scrivere un programma in linguaggio C

Introduzione al Linguaggio C

Codifica: dal diagramma a blocchi al linguaggio C++

Definire all'interno del codice un vettore di interi di dimensione DIM, es. int array[] = {1, 5, 2, 4, 8, 1, 1, 9, 11, 4, 12};

Istruzioni per il programma ANDI

Quotazione compareto( ) Quotazione piurecente( ) Quotazione Quotazione Quotazione non trovato count( )

Uso di base delle funzioni in Microsoft Excel

Studente (Cognome Nome): Corso di Informatica Corso di Laurea in Ingegneria Gestionale a.a Secondo Compitino 21 Dicembre 2006

2. Spiegare brevemente qual è la funzione del compilatore e la sua importanza per il programmatore.

Fondamenti di Informatica T-1, 2009/2010 Modulo 2 Prova d Esame 5 di Giovedì 15 Luglio 2010 tempo a disposizione 2h30'

ESERCIZI DI PROGRAMMAZIONE C/C++ per le classi terza

Linguaggio C. Fondamenti. Struttura di un programma.

OTTAVA ESPERIENZA DI LABORATORIO. L elaborazione dei files in C

I file di dati. Unità didattica D1 1

Automatizzare i compiti ripetitivi. I file batch. File batch (1) File batch (2) Visualizzazione (2) Visualizzazione

Informatica B. Sezione D. Scuola di Ingegneria Industriale Laurea in Ingegneria Energetica Laurea in Ingegneria Meccanica

puntatori Lab. Calc. AA 2007/08 1

Tipi primitivi. Ad esempio, il codice seguente dichiara una variabile di tipo intero, le assegna il valore 5 e stampa a schermo il suo contenuto:

Funzioni matlab per la gestione dei file. Informatica B Prof. Morzenti

ISTITUTO TECNICO INDUSTRIALE STATALE LA GESTIONE DEI FILE DI TESTO IN C++

CREAZIONE DI UN DATABASE E DI TABELLE IN ACCESS

ARCHIVIA PLUS - ARCHIFILE

Lab 11 Gestione file di testo"

Appunti sulla Macchina di Turing. Macchina di Turing

Variabili e tipi di dato

Aprire, preparare un documento da utilizzare come documento principale per una stampa unione.

Fondamenti di Informatica 2

Realizzazione di una classe con un associazione

Spiegazione Open Interest Storico:

Corso di Laurea in Ingegneria Gestionale Esame di Informatica a.a settembre 2011

Compito di Fondamenti di Informatica

Strutture. Strutture e Unioni. Definizione di strutture (2) Definizione di strutture (1)

Soluzioni degli esercizi di riepilogo (Fondamenti di Informatica 1 Walter Didimo)

Utilizzo del Terminalino

GENERAZIONE PREVENTIVI

Programmazione I - Laboratorio

Dati testuali. Caratteri e stringhe. Tipi di dato testuali. Dati testuali. Il sistema dei tipi C. Rappresentazione dei testi

2. LOGIN E RECUPERO DATI DI ACCESSO

Esercizi su. Funzioni

MAGAZZINO FISCALE (agg. alla rel )

Editor vi. Editor vi

Strutturazione logica dei dati: i file

INDICE. Accesso al Portale Pag. 2. Nuovo preventivo - Ricerca articoli. Pag. 4. Nuovo preventivo Ordine. Pag. 6. Modificare il preventivo. Pag.

Algoritmo. I dati su cui opera un'istruzione sono forniti all'algoritmo dall'esterno oppure sono il risultato di istruzioni eseguite precedentemente.

Esercizi di programmazione in C

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2

Note per generazione file.txt per invio trimestrale V.P. all AGENZIA DELLE ENTRATE

Una funzione è detta ricorsiva se chiama, direttamente o indirettamente, se stessa. In C tutte le funzioni possono essere usate ricorsivamente.

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2

Gestione dei File. dischi nastri cd

Arduino: Programmazione

Concetto di Funzione e Procedura METODI in Java

Compilatore risorse display grafico LCD serie IEC-line

SPC e distribuzione normale con Access

INFORMATICA - I puntatori Roberta Gerboni

Moduli (schede compilabili) in Word Esempio: scheda di alimentazione per un degente

APPUNTI SUL LINGUAGGIO DI PROGRAMMAZIONE PASCAL

Capitolo 2. Operazione di limite

SOMMARIO Coda (queue): QUEUE. QUEUE : specifica QUEUE

Vettori Algoritmi elementari di ordinamento

EXCEL FUNZIONI PRINCIPALI

Scheda operativa Versione rif c00. Libro Inventari

<?php include './include/page.php';

Inizializzazione, Assegnamento e Distruzione di Classi

Struttura a record. File ad accesso diretto. Modalità di apertura. Modalità di apertura

PROCEDURA INVENTARIO DI MAGAZZINO di FINE ESERCIZIO (dalla versione 3.2.0)

Richiesta pagina PHP (es: index.php)

lo PERSONALIZZARE LA FINESTRA DI WORD 2000

La selezione binaria

Appunti tratti dal videocorso on-line di Algoritmi e Programmazione Avanzata By ALeXio

Guida all uso di Java Diagrammi ER

Sistema operativo: Gestione della memoria

3 - Variabili. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Esercizio 1. Esercizio 1

ci sono più problemi che programmi esiste un problema che non si può risolvere con un programma

Teoria delle code. Sistemi stazionari: M/M/1 M/M/1/K M/M/S

Algoritmi su array / 2

Transcript:

Trattamento delle STRINGHE in C(++) Le cose che qui vengono dette valgono sia per il linguaggio C che per il C++. Nel linguaggio C non esiste, a differenza di quel che avviene per altri linguaggi di programmazione (ad es. il Pascal), un tipo predefinito per le stringhe. Esiste tuttavia un modo semplice per costruirle e una library (<string.h>) con tante utili funzioni per la loro elaborazione. In C una stringa viene costruita come un array di caratteri (char); i caratteri della stringa vanno dal primo carattere dell array (quello di indice 0) fino al primo carattere di Fine Stringa che si incontra andando avanti: il carattere di Fine Stringa che ha come valore 0 e sovente nei programmi lo si indica come '\0'. Tutte le funzioni di <string.h> fanno riferimento alle stringhe come ad un dato che ha la struttura appena descritta e che è illustrata in figura: Come già sappiamo, quando si dichiara un array, per il linguaggio C il nome dell array da solo rappresenta un puntatore (indirizzo) al byte dell area di memoria a partire dal quale l array stesso viene memorizzato. Nel caso delle stringhe (=array di char) il loro nome dà quindi l indirizzo del primo carattere della stringa: gli altri caratteri sono tutti quelli successivi fino al primo byte nullo (=0='\0') che s incontra (Fine Stringa, che non fa parte della stringa). Ovunque in un programma compare una stringa costante (successione di caratteri delimitata dai apici doppi " ") il compilatore, dopo aver memorizzato i caratteri della stringa in una opportuna area di memoria, sostituisce alla stringa costante il puntatore all area di memoria nella quale i caratteri della stringa sono stati memorizzati, proprio come fa con le stringhe variabili dichiarate come array di char. Questo consente, ovunque sia richiesta una stringa come parametro di input, di mettere indifferentemente sia una stringa costante che una variabile. Attenzione! Essendo la fine di una stringa data dal primo carattere di Fine Stringa che s incontra andando avanti in memoria dopo l inizio della stringa, per le stringhe variabili, se ci si dimentica di mettere il Fine Stringa, questo potrebbe anche essere trovato fuori dall area riservata alla stringa con la corrispondente dichiarazione di array di caratteri: come noto il C, per essere efficiente, evita molti controlli tra cui anche quello di andar fuori dall area riservata ad un array e questo può allora portare ad imprevedibili e non segnalati errori. Il programmatore dovrà comunque preoccuparsi di evitarli. Adesso verrà fatta una breve descrizione delle funzioni di uso più frequente della library <string.h> e di alcune di queste viene presentata una versione casalinga rifatta come esercizio sulle stringhe per cercare possibilmente di riuscire a comprenderle meglio. Queste 118

funzioni rifatte sono state messe in un file stringhe.h e se si vogliono usare in un programma, senza riscriverle, basterà mettere un #include "stringhe.h", purché naturalmente si abbia il file stringhe.h nel direttorio cartella in cui si sta lavorando. Alcune funzioni della library sono descrtte negli appunti sull I/O: gets(); puts(); per leggere/scrivere stringhe da/su tastiera/schermo; fgets(); fputs(); per leggere/scrivere stringhe da/su file. Poi ci sono due funzioni che servono per leggere / scrivere da/su stringa: sscanf(ss,"specificazioni", lista punt. var. input); sprintf(ss,"specificazioni", lista valori di output); Lo scopo di sscanf() è quello di prendere da una stringa ss (che può essere sia costante che variabile) dei dati, ovviamente sotto forma di caratteri, e trasferirli/convertirli secondo le "Specificazioni" nelle aree di memoria individuate dalla lista punt. var. input. Seguono due esempi: int i,k; float f,g; double d,e; sscanf("134 7.375 781.97 12500 23861495.123847 1.23E 88", "%i %f %f %lf %lf %d", &i, &f, &g, &k, &d, &e); trasferisce in i, f, g, k, d, e, secondo la relativa specificazione, i valori numerici: 134 7.375 781.97 12500 23861495.123847 1.23E 88 char tt[35]=" 112 4.75 Z 193.874 Giuseppe 132", w[12], c; int n,m; float f; double d; sscanf(tt,"%d %f %c %lf %s %i", &m, &f, &c, &d, w, &n); trasferisce in m, f, c, d, w (notare l assenza di & perché w è già un puntatore), n, secondo la relativa specificazione, i seguenti oggetti: 112 4.75 'Z' 193.874 "Giuseppe" e 132 (gli apici ' e " sono usati per far capire che in un caso si tratta del carattere Z e nellaltro della stringa Giuseppe, ma non sono ovviamente memorizzati). Lo scopo della funzione sprintf() è quello mettere su una stringa (ss) i caratteri che con le analoghe funzioni printf() e fprintf() andrebbero rispettivamente sullo schermo o su un file. Ad esempio, col frammento di programma char riga[81], st[12]="stringa", ch='q'; int m=4; float ff=158.376; double d=1.2345678901468e 127; sprintf(riga,"%3d %8.4f %2c %10s% 20.12le %s", m,ff,ch,st,d,"fine"); sulla stringa riga verrebbero memorizzati i caratteri (si è indicato con un blank): 4 158.3760 Q Stringa 1.234567890147e 127 Fine Spesso è utile sapere quanto è lunga una stringa, cioè quanti sono i caratteri che sono compresi tra l inizio della stringa ed il carattere di Fine Stringa (escluso, vedi figura iniziale). Per 119

questo scopo nella library <string.h> c è la funzione strlen(char *s) che qui viene rifatta col nome lung(): int lung(char s[]) int k= 1; while (s[++k]); // Si ferma quando s[k]==0 = fine stringa return k; // Indice fine stringa = lunghezza stringa La funzione strcmp(char *s1, char *s2) fa il confronto lessicografico tra le due stringhe s1 ed s2 e restituisce un valore <0 se s1<s2, =0 se s1=s2 e >0 se s1>s2. Qui viene rifatta col nome confr() (che restituisce rispettivamente 1, 0 e 1): int confr(char s1[], char s2[]) int k=0; while (s1[k] == s2[k] && s1[k]) k++; if (s1[k]>s2[k]) return 1; if (s1[k]<s2[k]) return 1; return 0; La funzione strcmpi(char *s1, char *s2) fa il confronto lessicografico tra le due stringhe s1 ed s2 senza considerare significativa la differenza maiuscolo minuscolo e restituisce un valore ancora <0 se s1<s2, =0 se s1=s2 e >0 se s1>s2. Qui viene rifatta col nome confr_i() (nella quale la distinzione tra maiuscolo e minuscolo viene eliminata trasformando con la funzione toupper() tutti i caratteri alfabetici in maiuscolo): int confr_i(char s1[], char s2[]) int k=0; while (toupper(s1[k])==toupper(s2[k]) && s1[k]) k++; if (toupper(s1[k])>toupper(s2[k])) return 1; if (toupper(s1[k])<toupper(s2[k])) return 1; return 0; La funzione strcpy(char *s1, char *s2) fa sulla stringa s1 una copia della stringa s2. Qui viene rifatta una funzione analoga col nome copia(): void copia(char s1[], char s2[]) 120

int i=0; do s1[i] = s2[i]; while (s2[i++]); La funzione strcat(char *s1, char *s2) appende alla fine della stringa s1 una copia della stringa s2 (s2 rimane invariata). Qui viene rifatta la funzione col nome concat(): void concat(char s1[], char s2[]) int k1= 1,k2=0; while (s1[++k1]); // si esce quando s1[k1] == fine stringa do s1[k1++] = s2[k2]; while (s2[k2++]); La funzione char *strstr(char *s1, char *s2) verifica se la stringa s2 è contenuta nella stringa s1 e, in caso affermativo restituisce un puntatore al carattere di s1 a partire dal quale è contenuta la stringa s2; in caso negativo restituisce un puntatore NULL (=0). Qui viene rifatta una funzione analoga, col nome posiz(), ma che restituisce come risultato l indice del carattere di s1 a partire dal quale è contenuta la stringa s2; in caso negativo restituisce un valore negativo ( 1). int posiz(char s1[], char s2[]) int i,j,l1= 1,l2= 1; while (s1[++l1]); while (s2[++l2]); l1 = l2; for (i=0; i<=l1; i++) if (s1[i] == s2[0]) j=1; while (j<l2 && s1[i+j] == s2[j]) j++; if (j==l2) return i; return 1; Seguono ora altre tre funzioni esercizi sulle stringhe che non fanno parte della library <string.h>. La funzione cancel() cancella nella stringa s num caratteri a partire da pos (o eventualmente meno se da pos alla fine di s ce ne sono meno) void cancel(char s[], int pos, int num) 121

int k= 1; while (s[++k]); num += pos; k = (num<k)? num : k; do s[pos++] = s[k]; while (s[k++]); La funzione copy() copia num caratteri di s2 a partire da pos su s1. Se ne copiano meno se da pos alla fine di s2 ce ne sono meno di num. void copy(char s1[], char s2[], int pos, int num) int i=0; num += pos; while (s2[pos] && pos<num) s1[i++] = s2[pos++]; s1[i] = '\0'; La funzione insert() inserisce nella stringa s1, a partire dalla posizione pos, i caratteri della stringa s2 (senza verifiche di alcun tipo). void insert(char s1[], char s2[], int pos) int i= 1,k= 1; while (s1[++i]); while (s2[++k]); for (; i>=pos; i ) s1[i+k] = s1[i]; for (i=0; i<k; i++) s1[pos++] = s2[i]; Esempio di utilizzo delle funzioni precedenti. Supponiamo di dover fare delle lettere personalizzate per i clienti di una certa ditta. Possiamo preparare la lettera come file di testo mettendo 4 $ nei punti in cui deve andare il nome del cliente. Prendiamo una riga della lettera e mettiamola in una stringa dichiarata come char riga[81]; supponiamo che nome e cognome del cliente siano contenuti nella stringa char nome[36]; se in riga è contenuta la stringa $$$$ la cancelliamo e dove si trovava andiamo a inserire la stringa nome. Segue un pezzo di programma che, supponendo di avere già in riga e nome i dati suddetti, se è il caso fa l operazione suddetta. char riga[81], nome[36], k;... k=posiz(riga, $$$$ ); if (k>=0) // Se k>=0 $$$$ è presente 122

cancel(riga,k,4); // Si cancella la sottostringa $$$$ insert(riga,nome,k); // Si inserisce nome al posto di 123