Newsgroup: it.comp.lang.c
Titolo: Concatenazione e copia di stringhe.

	Ciao.
Il semplice programma che vi posto di seguito legge due strinbghe ed 
esegue su di esse alcune funzioni scritte da me per esercizio, che sono 
uguali a quelle presenti nella libreria standard. 
Per motivi che mi sfuggono, dopo l'esecuzione della funzione concat 
(equivalente a strcat), la stringa s2 viene privata del primo carattere, 
nonostante concat non ne preveda la modifica. 
Potete rendervene conto guardando il risultato della funzione copia 
(equivalente a strcpy).
Potreste aiutarmi a capire perché ciň accade? 
Un saluto e grazie mille per l'aiuto che sempre mi date.
Bizio.
***
/*Legge due stringhe costanti e le manipola utilizzando funzioni che 
sono
copie di quelle presenti in string.h. */
#include <stdio.h>
size_t lunghezza(char *s);
char *concat(char *s1, const char *s2);
char *copia(char *s1, char *s2);
int main(void)
{
 char *s1, *s2;
 size_t lung;
 s1 = "Pierino ";
 s2 = "insiste";
 printf("%s%s\n%s%s\n", "s1 = ", s1, "s2 = ", s2);
 lung = lunghezza(s1);
 printf("%s%u\n", "lunghezza(s1) = ", lung);
 s1 = concat(s1, s2);
 printf("%s%s\n", "concat(s1, s2) = ", s1);
 s1 = copia(s1, s2);
 printf("%s%s\n", "copia(s1, s2) = ", s1);
 return 0;
}
//restituisce la lunghezza di s, escluso \0. Copia di strlen.
size_t lunghezza(char *s)
{
 int i = 0;
 while (*s != '\0') {
  ++s;
  ++i;
 }
 return i;
}
//Concatena s1 ed s2 e pone il risultato in s1. Copia di strcat.
char *concat(char *s1, const char *s2)
{
 char *p = s1;
 while (*p != '\0')
  ++p; //salta s1
 while (*p = *s2) { //occhio che nella parentesi c'č un assegnamento e 
non un test...
  ++p; //l'espressione tra parentesi copia s2 in s1
  ++s2;
 }
 return s1;
}
//copia s2 in s1. Restituisce s1. Copia di strcpy.
char *copia(char *s1, char *s2)
{
 char *p = s1;
 while ((*p = *s2) != 0) {
  ++p;
  ++s2;
 }
 return s1;
}

  s2 = "insiste";
s1 in questo modo sta puntando all'inizio
dell'array di caratteri che contiene "Pierino".
non vedo istruzioni nel tuo codice per
allocare spazio aggiuntivo per contenere la
concatenazione... quindi quando copi
"insiste" lo stai copiando in una zona
di memoria che probabilmente e' dedicata
ad altri scopi.
I casi sono 2:
o la stringa iniziale (quella a cui vuoi concatenare)
e' contenuta in un array di caratteri che e' gia'
bastevole ad accogliere il risultato della concatenazione,
oppure devi allocare al momento un array abbastanza
grande da contenenere l'allocazione.
Altrimenti quello che vai e' andare a scrivere dei caratteri
in punti piu' o meno a caso della memoria: e questo e' *MALE*:
se sei fortunato il programma si pianta brutalmente, se sei
sfortunato il programma puo' funzionare 100 volte e piantarsi
la 101-esima.
Insomma tieni presente che in C non c'e' una gestione automatica
dello spazio necessario alle stringhe, quindi devi preoccuparti
tu (anche se usi la strcat o la strcpy di libreria) che sia stato
allocato lo spazio per le tue stringhe.
Tassativo studiarsi l'allocazione
dinamica (malloc, realloc, etc.) prima di mettersi a maneggiare le stringhe.
( Il codice probabilmente contiene diversi errori di questo tipo,
non l'ho controllato tutto).
ciao,
g.

 ad altri scopi.
Ciao Giovanni e tutti.
Quel che dici non fa una piega, ma il malfunzionamento che riscontro io 
è un altro. 
Compilando ed eseguendo il programma, ci si accorge che la 
concatenazione riesce perfettamente, ma, al termine di essa, la 
variabile s2 punta alla stringa "nsiste" anziché alla stringa "insiste". 
Insomma, nonostante non venga modificata dalla funzione concat, s2 si 
mangia il primo carattere della stringa a cui punta. 
C'è una spiegazione per questo comportamento?
Ciao e grazie mille a tutti.
Bizio.
p.s. Ho provato anche con stringhe di dimensioni più grandi, con lo 
stesso risultato.


....
  char 	s1[1024] = "Pierino ",
  	s2[1024] = "insiste";
  concat(s1, s2);
  printf("%s%s\n", "concat(s1, s2) = ", s1);
  copia(s1, s2);
  printf("%s%s\n", "copia(s1, s2) = ", s1);
....
ps: leggiti la differenza che passa tra un puntatore a una 'constante' 
stringa (eg. char *s1 = "...";) ed un array di car. inizializzato come 
sopra.
ciao
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com

 è un altro. 
Evidentemente non sono stato chiaro.
IL TUO PROGRAMMA CONTIENE DELLE ISTRUZIONI CHE CAUSANO
LA SOVRASCRITTURA DI AREE DI MEMORIA CHE IL COMPILATORE
STA PROBABILMENTE USANDO PER ALTRI SCOPI.
Quindi puo' avere dei comportamenti totalmente
impredicibili, tra cui
1) stampare il risultato esatto
2) andare in crash dando un bel "segmentation fault" come succede
a me se tento di far girare il tuo programma
3) stampare cose piu' o meno a caso
Quindi non ha alcun senso interrogarsi sul comportamento
di un programma cosi' platealmente errato, perche' gli
errori di sforamento di un array possono causare i comportamenti
piu' bizzarri.
In particolare, anche se non l'ho controllato,
il tuo programma sembra funzionare se uno lo
modifica in
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
size_t lunghezza(char *s);
char *concat(char *s1, const char *s2);
char *copia(char *s1, char *s2);
int main(void)
{
 char *s1, *s2;
 size_t lung;
 s1=malloc(1000);
 s2=malloc(1000);
 strcpy(s1,"Pierino ");
 strcpy(s2,"insiste ");
 printf("%s%s\n%s%s\n", "s1 = ", s1, "s2 = ", s2);
 // eccetera eccetera
in questo modo ho allocato un bel' po di spazio (1000 caratteri)
e uno si puo' sbizzarrire a fare un po' di concatenazioni e copie.
ciao,
g.