Allora prima di tutto non puoi usare una sola variabile char.. ogni carattere ha un determinato codice per identificarlo e che è di un byte(8 bit) ciò significa che ogni carattere memorizzato è un byte...

Una variabile di tipo char è fatta apposta per memorizzare un solo byte quindi un solo carattere..

I problemi quindi si dovrebbero presentare con le stringhe...

Il C mette a disposizione la possibilità di avere delle stringhe e il metodo più conosciuto sono gli array di caratteri...

A quanto ho letto tu non sai bene usare i puntatori quindi ti faccio una breve spiegazione

In C esistono fondamentalmente due tipi di variabili.. le variabili normali che usiamo per memorizzare dei valori e altri tipi di variabili che vengono chiamati puntatori...

Queste variabili a differenza di quelle normali non contengono un valore numerico ma un indirizzo della memoria...

facciamo un esempio:

int ciao=5; questa variabile è normale e contiene il valore 5

-----------------------------------------------------------------

int *p; dichiaro una variabile di puntatore a interi
p=&ciao; dico che p dovrà contenere l'indirizzo della memoria
in cui c'è la variabile ciao quindi dove c'è il valore 5

dopo che ho fatto un assegnamento del genere se andrò a
stampare la variabile puntatore in output verrà
mandato l'indirizzo, mentre se la stampo con un
asterisco davanti mi verrà mandato in output il valore
che punta:

esempio

-printf("l'indirizzo è %d",p);

verrà stampato l'indirizzo a cui punta il puntatore

-printf("il valore a cui punta è %d",*p);

verrà stampato il valore 5 che è contenuto nell'indirizzo di
memoria contenuto nel puntatore.. si dice che punta a quel valore

fai comunque delle prove per avere delle idee più chiare.. torniamo quindi alle stringhe...

queste non sono altro che caratteri messi in memoria in locazione successive...

per esempio se prendo in input la parola ciao con una normale funzione di input che può essere la gets o la scanf in memoria avrò una robe del genere

cassetto 200 = c
cassetto 201 = i
cassetto 202 = a
cassetto 203 = o

diciamo che realmente non è proprio così ma questo aiuta a capire... con 200,201.... ho indicato l'indirizzo dei cassetti cioè delle locazioni

quindi in memoria i caratteri delle stringhe vengono memorizzati successivamente...

quando dichiariamo un vettore di array tante locazioni quant'è grosso l'array (es.char vet[500] saranno 500 locazioni) vengono svuotate da valori vecchi che non servono più che saranno ora disponibili per memorizzare la stringa...

adesso passiamo alla funzione malloc....

con questa è possibile allocare(cioè liberare della memoria per renderla diponibile per altri dati.. come succedeva con i vettori) solo che qua il numero delle locazioni cioè in questo caso dei caratteri può essere cambiato in maniera dinamica: posso sempre tenere sotto controllo il numero delle locazioni che uso per la stringa e quindi aumentarle se non bastano ma quindi anche cancellarle se ce ne sono troppe(funzione realloc) cosa che non posso fare con gli array di caratteri...

malloc si usa così

p=(char *)malloc(50)


adesso ti spiego...

prima dell'uguale c'è p che è un puntatore e che memorizzerà il valore restituito dalla funzione...

se malloc parte ad allocare dalla locazione 200 e in questo caso arriva alla 250 la funzione restituirà 200 cioè dove inizia nel nostro caso la stringa

dopo l'uguale c'è (char *).. questa operazione comune in C è detta cast.. la funzione malloc restituisce un tipo void cioè di nessun tipo.. tocca a me quindi con quell'operazione detta cast convertire il void in char cioè portare da tipo indefinito a tipo carattere..

dopo ho messo la funzione che prende come argomento lo spazio da allocare, cioè nel nostro caso il numero di caratteri che la stringa dovrà occupare...

il tuo problema però era quello di cambiare il numero di caratteri in modo tale che se erano troppi liberasse quelli inutilizzati..

a sto punto ti spieherò un istruzione che è la sizeof e una funzione che è la realloc

la sizeof restituisce un tipo intero e prende come unico argomentoo un tipo di dato o un puntatore...

se io faccio sizeof(int) questo restituirà 4 perchè sugli attuali computer gli interi occupano 4 byte.. se provo con char avrò 1..

se provo con un puntatore tipo la stringa che avevamo sopra avremo 50 perche malloc ha allocato 50 cassetti...

adesso la realloc... questa serve per ridimensionare un area di memoria creata con malloc...

è così: s=realloc(p,25)

restiutisce una nuova area di memoria contenente il valore di p cioè della vecchia stringa ma con un numero di byte inferiore cioè passa dai vecchi 50 a 25...

quindi alla fine potrei fare così:

char *s,*p;

p=(char *)malloc(200);
printf("\nInserisci una stringa : %s");
gets(p);
s=realloc(p,100)

adesso abbiamo una nuova stringa che è come la vecchia ma occupa la metà.. è passata da 200 a 100....

spero quindi che tu abbia capito... non è complesso e provando un po riesce a fare anche di meglio... ciao ciao e buon lavoro!!