Concatenare Stringhe in Linguaggio C
Un'operazione comune che si presenta, spesso, quando si lavora con le stringhe è la concatenazione di due stringhe. Il linguaggio C non fornisce un operatore per concatenare due stringhe come fanno molti altri linguaggi.
Tuttavia, possiamo usare le funzioni strcat
e strncat
della libreria standard string.h
per concatenare due stringhe in linguaggio C.
Esse accettano due puntatori a stringa e concatenano la seconda stringa alla fine della prima. Inoltre, restituiscono il puntatore alla prima stringa.
In questa lezione vedremo come utilizzare le funzioni strcat
e strncat
per concatenare due stringhe in linguaggio C. Inoltre, vedremo come implementare manualmente queste funzioni per capirne meglio il funzionamento e i problemi intrinseci.
Funzione strcat
- Concatenazione di stringhe
In linguaggio C non possiamo usare l'operatore di somma +
, come fanno molti altri linguaggi, per concatenare due stringhe.
Possiamo, invece, usare la funzione strcat
della libreria standard string.h
.
La funzione strcat
accetta due puntatori a stringa e concatena la seconda stringa alla fine della prima. Inoltre, restituisce il puntatore alla prima stringa.
La sua firma è:
char *strcat(char *dest, const char *src);
Dove:
dest
è il puntatore alla stringa di destinazione, cioè la stringa a cui vogliamo aggiungere la seconda stringa.src
è il puntatore alla stringa sorgente, cioè la stringa che vogliamo aggiungere alla stringa di destinazione.
Vediamo un esempio:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
In questo esempio, definiamo due array di caratteri s
e t
e li inizializziamo con le stringhe "Hello"
e "World"
. Poi, concateniamo la stringa t
alla stringa s
usando la funzione strcat
. Infine, stampiamo il risultato.
Il programma stampa:
Prima: Hello
Seconda: World
Dopo: HelloWorld
Come possiamo vedere, la stringa t
è stata concatenata alla stringa s
.
Il valore di ritorno della funzione strcat
è spesso ignorato, poiché restituisce il puntatore alla stringa di destinazione, che è lo stesso puntatore passato come primo argomento. Tuttavia, possiamo usarlo per concatenare più stringhe in una sola riga di codice:
char s[128] = "Hello";
char t[128] = "World";
char u[128] = "!";
strcat(s, strcat(t, u));
In questo caso, la stringa u
è concatenata alla stringa t
; successivamente, il risultato di questa operazione, ossia t
, è concatenato alla stringa s
.
Il risultato finale è:
u
conterrà"!"
;t
conterrà"World!"
;s
conterrà"HelloWorld!"
.
Funzione strcat
La funzione strcat
accetta due puntatori a stringa e concatena la seconda stringa alla fine della prima. Inoltre, restituisce il puntatore alla prima stringa.
Essa è definita nella libreria standard string.h
:
#include <string.h>
La sua firma è:
char *strcat(char *dest, const char *src);
dest
è il puntatore alla stringa di destinazione, cioè la stringa a cui vogliamo aggiungere la seconda stringa.src
è il puntatore alla stringa sorgente, cioè la stringa che vogliamo aggiungere alla stringa di destinazione.
Il valore di ritorno è il puntatore alla stringa di destinazione: dest
.
La funzione strcat
non è sicura
La funzione strcat
non verifica se la stringa di destinazione ha abbastanza spazio per contenere se stessa e la stringa sorgente. Se la stringa di destinazione non ha abbastanza spazio, la funzione può sovrascrivere la memoria adiacente, causando comportamenti indefiniti.
Per evitare questo problema, possiamo usare la funzione strncat
, che accetta un terzo argomento che specifica il numero massimo di caratteri da concatenare.
Funzione strncat
- Concatenazione di stringhe con limite
Per evitare il problema di strcat
, possiamo usare la funzione strncat
della libreria standard string.h
.
La funzione strncat
accetta due puntatori a stringa e un limite superiore e concatena la seconda stringa alla fine della prima, fino al limite superiore. Inoltre, restituisce il puntatore alla prima stringa.
La sua firma è:
char *strncat(char *dest, const char *src, size_t n);
Dove:
dest
è il puntatore alla stringa di destinazione, cioè la stringa a cui vogliamo aggiungere la seconda stringa.src
è il puntatore alla stringa sorgente, cioè la stringa che vogliamo aggiungere alla stringa di destinazione.n
è il numero massimo di caratteri da concatenare, escluso il terminatore\0
.
Vediamo un esempio di utilizzo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
In questo esempio, definiamo due array di caratteri s1
e s2
e li inizializziamo con le stringhe "Hello"
e "World"
.
Poi, concateniamo la stringa s2
alla stringa s1
usando la funzione strncat
. Il terzo argomento passato alla funzione è il numero massimo di caratteri da concatenare, che è calcolato come la differenza tra la dimensione massima dell'array s1
, MAX_SIZE
, e la lunghezza attuale della stringa s1
, ottenuto con la funzione strlen
, meno 1 per il terminatore \0
.
L'output del programma sarà:
Prima: Hello
Seconda: World
Dopo: HelloWorld
Calcolare il numero di caratteri da concatenare
Se dobbiamo concatenare due stringhe, s
e t
, e sappiamo che la stringa di destinazione, s
, ha una dimensione massima di MAX_SIZE
, possiamo calcolare il numero di caratteri da concatenare come:
MAX_SIZE - strlen(s) - 1
Questo perché alla stringa di destinazione possiamo aggiungere un numero di caratteri pari alla sua lunghezza massima, meno la sua lunghezza attuale, meno 1 per il terminatore \0
.
Per cui, l'utilizzo tipico di strncat
è:
strncat(s, t, MAX_SIZE - strlen(s) - 1);
Implementazione di strcat
e strncat
Anche in questo caso, è utile, dal punto di vista didattico, implementare le funzioni strcat
e strncat
manualmente. In questo modo possiamo capirne meglio il funzionamento e i problemi intrinseci.
Partiamo dalla funzione strcat
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Analizziamo il codice. La funzione utilizza un puntatore locale, p
, con cui scorre la stringa di destinazione. In particolare, utilizza due cicli while
:
- Il primo ciclo
while
, righe 4-6, scorre la stringa di destinazione fino a trovare il terminatore\0
; - Dopo questo ciclo
while
abbiamo che il puntatorep
punta al terminatore\0
della stringa di destinazione. Questo terminatore andrà sostituito con il primo carattere della stringa sorgente,src
. Per fare ciò, utilizziamo un secondo ciclowhile
, righe 8-12, che copia i caratteri della stringa sorgente nella stringa di destinazione.
Infine, la funzione pone il terminatore \0
alla fine della stringa di destinazione e restituisce il puntatore ad essa.
Il problema della strcat
sta proprio nel fatto che i due cicli while
non controllano se la stringa di destinazione ha abbastanza spazio per contenere se stessa e la stringa sorgente. Non solo, ma non controllano nemmeno se i due puntatori alle stringhe passati come argomenti puntano a stringhe valide.
La funzione strncat
risolve il primo problema. Vediamone una possibile implementazione che chiameremo mia_strncat
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
La funzione mia_strncat
è simile alla mia_strcat
, ma ha un terzo argomento, n
, che rappresenta il numero massimo di caratteri da concatenare. La differenza principale rispetto alla strcat
sta nel secondo ciclo while
, righe 8-13, che controlla anche il numero di caratteri da concatenare.
Infatti, la condizione *src != '\0' && n > 0
controlla se il carattere corrente della stringa sorgente è diverso dal terminatore \0
e se il numero di caratteri da concatenare è maggiore di 0. Inoltre, all'interno del ciclo while
, decrementiamo il contatore n
ad ogni iterazione.
In questo modo, la funzione mia_strncat
non concatenerà più di n
caratteri, evitando così di sovrascrivere la memoria adiacente.
In Sintesi
In linguaggio C, possiamo concatenare due stringhe usando la funzione strcat
della libreria standard string.h
. Questa funzione accetta due puntatori a stringa e concatena la seconda stringa alla fine della prima. Tuttavia, la funzione strcat
non verifica se la stringa di destinazione ha abbastanza spazio per contenere se stessa e la stringa sorgente, causando comportamenti indefiniti.
Per evitare questo problema, possiamo usare la funzione strncat
, che accetta un terzo argomento che specifica il numero massimo di caratteri da concatenare.
Entrambe le funzioni restituiscono il puntatore alla stringa di destinazione.
Inoltre, abbiamo visto come implementare manualmente le funzioni strcat
e strncat
, per capirne meglio il funzionamento e i problemi intrinseci.
Nella prossima lezione vedremo come confrontare stringhe in linguaggio C.