Newsgroup: it.comp.lang.c
Titolo: Di nuovo stringhe...

Salve, sto studiando il C "passo dopo passo", ma scivolo sulle stringhe...
Vorrei alcuni chiarimenti, confermandomi o meno alcune cosette.
...purtroppo e' un po lungo...
----------------
Dichiarare
  char *str = "pippo";
equivale a
  char *str;
  str = pippo;
?
In ogni caso credo che il contenuto di str sia costante (=pippo) e non possa
piu' essere modificato.
----------------
Questo codice e' giusto?
Se si, la stringa "pippo" dove va a finire in memoria?
char * myfunc (void) {
return ("pippo");
}
main () {
printf("%s",myfunc());
}
----------------
Questo codice funziona
char * myfunc (void) {
char *str;
str = (char*)malloc(10*sizeof(char));
gets(str);
return (str);
}
main () {
printf("%s",myfunc());
}
perche' se uso scanf("%s",&str); invece di gets(str); non appena batto invio
sulla scanf mi da un run time error?
Inoltre, dove devo mettere free(str) per liberare la memoria allocata?
----------------
E' giusto? ...sembra funzionare...
char * myfunc (void) {
char str[10];
strcpy(str,"pippo");
return (str);
}
main () {
printf("%s",myfunc());
}
Perche' in compilazione mi da un warning "function returns address of local
variable"? Che significa??
----------------
E' giusto creare una funzione che ritorna una stringa in questo modo:
char * myfunc (void) {
char *str;
...malloc...
.....
return (str);
}
----------------
Ho capito come creare array si stringe utilizzando char *myarray[SIZE];
Ha senso una funzione che ritorna un array di stringhe? Se si, come si puo'
implementare?
----------------
Grazie in anticipo
Enrico

Enrico
Ciao,
Maurizio

 ora il sonno mi assale =P
e' possibile farlo ed in piu' modi.
pensa ad un caso in cui tale cosa ti sarebbe utile e poi proviamo di vedere
in quale modo si puo' fare...
Tommy

   str = pippo;
 qui mi ero dimenticato le "" -> str="pippo"; Lo chiedo perche' ho visto un
esempio dove prima dichiarano la variabile e poi la assegnano senza usare
malloc (Teach yourself C in 21 days);
Tornando al nuovo.
Ho capito il passaggio per riferimento nel caso semplice di variabili
intere, ad esempio
void cambia(int * t) {
*t = 20;
}
main () {
 int x = 10;
 cambia(&x);
 printf("%d",x);
}
In pratica nei paramentri della funzione metto * e nell'argomento della
funzione metto &.
Ma nel caso volessi passare una stringa per riferimento, e' giusto
utilizzare il codice qui sotto (che compilandolo sembra funzionare
correttamente),
void checkslash (char temp[100]) {
 int i=strlen(temp);
 if (temp[i-1]!='/') {
   temp[i]='/';
   temp[i+1]='\0';
 }
}
main () {
 char str[100];
 strcpy(str,"/home/pippo");
 checkslash (str);
 printf("%s",str);
}
Perche' non funziona se metto * e & come nell'esempio di prima ? Forse
perche' str e' gia' l'indirizzo della stringa e temp e' un puntatore?
Ancora grazie
Enrico

myfunc(), tale inidirizzo viene usato nella printf per stampare la stringa.
Una volta che viene deallocata la memoria nella funzione non c'e'
sicurezza di cosa troverai a quell'indirizzo...
ecco cosa da in output questo codice ad esempio
------------code---------------
#include <stdio.h>
#include <string.h>
char * myfunc (void) 
 {
   char str[10];
   strcpy(str,"pippo");
   return (str);  
 }
int main ()
 {
   char *p = "prova";
 
   printf("%s",p);
   printf("%s",myfunc());
 
  return 0;
 }
-------------end code-----------------
-------------output-----------------
prova
 ｳaｻ @
--------------end output-----------------
se per caso la seconda printf stampa pippo....bhe.... e' pura
fortuna.... significa che quella locazione di memoria (liberata al
termine della funzione, non e' stata utilizzata dal sistema operativo
o dal programma stesso....
Ciao,
Maurizio


Questo funziona
------------------------------------------
#include <stdio.h>
void checkslash (char (* temp)[100]) {
  int i=strlen(*temp);
  if ((*temp)[i-1]!='/') {
    (*temp)[i]='/';
    (*temp)[i+1]='\0';
  }
}
main () {
  char str[100];
  strcpy(str,"/home/pippo");
  checkslash (&str);
  printf("%s",str);
}
------------------------------------------
Ciao,
Ema

 o dal programma stesso....
non se usi la stringa costante.
L'esempio su cui rispondevo era:
return ("pippo");
ed ora tu te ne salti fuori con un:
return (str);
Sono due cose diverse!
Tommy

diverso.
Credevo che avessi risposto a un'altro caso... ho commesso una svista
sorry
Ciao,
Maurizio

 dove str e' : char str[10]
In questo caso (anche se non c'entra niente, eh!) possiamo introdurre
uno -static-.
Ciao,
Paolo

 uno -static-.
Si, verissimo!
Pero' devi stare attento con static....supponiamo di avere una funzione che
dato un intero resituisce una stringa con tale intero: 6 -> "Ho 6 mele".
Questa funzione usa static come dici tu.
s1 = myfunc(6);
s2 = myfunc(4);
printf("%s\n",s1);
printf("%s\n",s2);
a questo punto potresti pensare che s1 sia "Ho 6 mele" e s2 sia "Ho 4 mele".
Non e' cosi'!
Entrambi stamperanno "Ho 4 mele".
Questo e' il problema di usare static. Per questo motivo bisognerebbe sempre
copiare con strcpy() invece di usare l'assegnamento (=). (oppure usare il
printf subito dopo le chiamata a funzione...)
A parte questo problemino, static funziona bene!
Tommy

 Tommy
Giusta osservazione.
Per chiarezza possiamo completare aggiungendo che č dovuto in quel caso
all'effetto di trovare verificate le seguenti:
s1 == s2  VERO, dopo le rispettive chiamate, ossia:
myfunc(x) == myfunc(qualsiasi)   VERO
perchč puntano sempre alla medesima locazione di memoria.
Ciao,
Paolo