Newsgroup: it.comp.lang.c
Titolo: passare una stringa PER INDIRIZZO ad una funzione

salve,
come diamine si fa a passare una stringa di caratteri per indirizzo
anziche' per valore?
sto codando una funzione che dovrebbe convertire una stringa sostituendo
gli spazi con "%20". ho quindi la necessita' di modificare quello che
passo alla funzione all'interno della funzione stessa.
naturalmente con questo prototipo non worka:
void convert_space(char *string) {
immagino che debba usare doppi puntatori o cosa?
mio dio questa e' una delle poche cose che non ho ancora capito del C
nonostante che mastico abbastanza bene i puntatori...
-- 
 [ Failla Angelo Michele aka pallotron ----- Freaknet Medialab CT ]
 [ pallotron (at) 
freaknet.org
 || angelo.failla (at) 
freaknet.org
 ]
 [ W3C: 
http://pallotron.homeunix.org
 ------------- ICQ: 31112052 ]
 [ GPG Key ID: 97E9049F ----------- fetch it @ 
http://pgp.mit.edu
 ]
 [ fingerprint: 2E6B 6F9A A403 F283 6F7C D899 1765 9124 97E9 049F ]

 wrote in message
slrnbcp3rk.2...@terminus.pallotron.freaknet.org...


 nonostante che mastico abbastanza bene i puntatori...
void convert_space(char **string);
E poi la richiami cosě:
char str[] = "qualcosa";
convert_space(&str);
Ciao,
Cecco

 ha scritto nel messaggio
news:Ri0za.22497$lK4.6...@twister1.libero.it...

Dimenticavo: nella funzione per riferirti alla stringa, *str contiene
l'indirizzo della stringa, quindi ad esempio:
char * str_to_mod = *str;
e lavori su str_to_mod
Ciao,
Cecco

 convert_space(string, &stringa_mod);
grazie dell'interessamento, ma non ho ben capito.
sei sicuro che quello che hai scritto sia corretto?
ho provato con convert_space(char *string) richiamandolo con
convert_space(&tmp_string);
gcc bestemmia e mi da il seguente warning:
inet_lib.c:143: warning: passing arg 1 of `convert_space' from
incompatible pointer type
mi sa che abbandono l'idea di modificare un argomento della funzione e
mi faccio una return di una stringa mallocata dentro la mia funzione.


 incompatible pointer type
Infatti in base a quel prototipo strigna_mod devi passarla per valore:
char stringa[] = "qualcosa";
char stringa_mod[sizeof(stringa)+1];
convert_space(stringa, stringa_mod);
Ciao,
Cecco

 e lavori su str_to_mod
meno male che ti sei ricordato perche' stavo proprio chiedendomelo.
minkia devo fissarmi sto concetto. in effetti basta applicare la
definizione di puntatore! hehee!
cmq grazie, buona giornata



Veramente dovrebbe andare bene cosi'!
Quello che te vuoi modificare e' la stringa, non il puntatore, quindi va
bene cosi'.
E' vero che il passaggio dei parametri e' per valore, ma il parametro
passato per valore e' il puntatore, non cio' che e' puntato dal puntatore.
Mi spiego meglio:
----------------------------------------------
int main(void) {
    char url[256];
    sprintf(url,"
www.c.it/una
 bella frase con spazi.htm");
    convert_space(url);
    printf("%s",url);
    return 0;
}
----------------------------------------------
In questo modo ho all'esterno della funzione un puntatore a caratteri "url"
che punta alla stringa relativa.
Nella funzione "convert_space" avro' una copia di "url" in una nuova
variabile "string" ma attraverso quella copia del puntatore (e' una copia,
quindi l'indirizzo di memoria associato ai due puntatori e' lo stesso) posso
ugualmente accedere alla stringa a cui punta anche "url".
quindi all'interno della funzione "convert_space" posso modificare la
stringa:
----------------------------------------------
void convert_space(char * string) {
    int i;
    for (i=0; i<strlen(string); i++)
        if (string[i]==' ') string[i] = '_';
}
----------------------------------------------
e vedere le modifiche all'esterno.
Metti insieme i due pezzi di codice e prova.
Nota: all'interno della funzione non modifico "string" ma modifico
"string[i]", ovvero qualcusa puntato da string.
          Il passaggio per valore lo riconosci, perche' se all'interno della
funzione tu facessi
          string = NULL;
          all'esterno "url" non verrebbe modificato e punterebbe ancora alla
stringa.
Diverso sarebbe se dovessi allocare memoria all'interno della funzione.
Allora si', dovresti passare un "char * * string", ma questa e' un'altra
storia.
Ciao,
Ema

 immagino che debba usare doppi puntatori o cosa?
Chiariamo subito un punto: non sei stato chiaro!
una stringa in C e' un array di caratteri terminato da 0
e quindi univocamente determinata dall'indirizzo del suo primo
carattere.
Dico che non sei stato chiaro perche' non si capisce chiaramente
se vuoi che la stringa stessa venga modificata oppure
se vuoi mantenere la stringa originaria inalterata e ottenerne
un'altra che corrisponde a quella originale con gli spazi mutati
in "%20". E' chiaro che, siccome viene modificata la lunghezza
stessa della stringa (non e' una modifica carattere->carattere!)
allora lo scenario 2 (cioe' avere 2 stringhe) e' il piu'
semplice.
ecco come potrebbe essere definita la funzioncina in quel caso:
void code(char *orig, char *mod)
{
   char *p;
   p=mod; //puntatore che si muove nella 2nda string
    // scandisco i caratteri della prima stringa
    for (;*orig; orig++)
       if (*orig == ' ')
       {
          // e' un blank, copio i caratteri e
          // avanzo il puntatore
          strcpy(p,"%20"); p+=3;
       }
       else  *(p++)=*orig; // copio il carattere,avanzo p
    *p=0; //termino la seconda strings
}
questa sopra la puoi invocare come
code(s,t);
sia se hai definito s e t come
char *s, *t; (e poi s=malloc(333); t=malloc(1000);)
o se hai fatto direttamente
char s[100], t[300];
naturalmente puoi volere anche usare sempre e solo
una stringa. Pero' il problema e' che se ci
sono spazi la stringa si allunga, e allora di fatto
la devi cambiare (cioe' in pratica deallocare e riallocare,
oppure reallocare).
Allora, in quel caso devi avere in partenza stringhe allocate
dinamicamente cioe' definite come
char *s;  e poi allocate con malloc,
e non cose tipo char s[80];
altrimenti non funge.
E puoi fare qualcosa di questo tipo.
char *DeSpace(char *S)
{
   int n, nsp=0;
   char *newS;
   // conto gli spazi di S
   for (n=0; S[n]; n++) if (S[n]==' ') nsp++;
   // arrivato qui n e' uguale alla lunghezza di S
   // e nsp e' uguale al numero di blank
   if (nsp==0) return S; // non ho nulla da fare !
   // la nuova stringa sara' lunga 2*nsp caratteri in piu'
    newS=malloc(n+2*nsp+1);
    code(S,newS);
    free(S);
    return newS;
}
e invocarla come
char *s;
s=malloc(100);
strcpy(s,"Ciao pippo !");
s=DeSpace(s);
printf("<%s>\n",s);
oppure, se godi fisicamente nell'usare i doppi puntatori,
puoi fare qualcosa di simile: (ho tolto i commenti uguali a sopra)
void DeSpace2(char **iS)
{
   int n, nsp=0;
   char *newS, *S;
   S=*iS;
   for (n=0; S[n]; n++) if (S[n]==' ') nsp++;
   if (nsp==0) return;
    newS=malloc(n+2*nsp+1);
    code(S,newS);
    free(S);
    *iS = newS;
}
e invocarla cosi'
char *s;
s=malloc(100);
strcpy(s,"Ciao pippo !");
DeSpace2(&s);
printf("<%s>\n",s);
Spero di essere stato capito ! :-)
ciao,
g.

 storia.
e' un'altra storia! :p
difatti io devo fare una sostituzione di ' ' con "%20", e siccome il
rapporto e' di un carattere a 3 mi sa devo andare a suon di realloc
a scarti di 3 e via.
grazie cmq!


 g.
si si sei stato chiarissimo. SONO IO CHE SONO POCO CHIARO! 
eheeehe
grazie


gli spazi con "%20". ho quindi la necessita' di modificare quello che
   Ho visto anche gli altri tuoi messaggi in questo thread.
Personalmente preferisco evitare di restituire un puntatore allocato
all'interno di una funzione, l'esperienza mi ha insegnato che e`
facile dimenticare di liberare l'area nella funzione chiamante. Se
proprio devo, di solito lo specifico bene nel nome della funzione
(qualcosa tipo `alloc_convert_space'). Vabbe', potrebbe essere una
tara personale, comunque ti propongo due funzioni, anziche` una sola.
Ammira la mia illegibilita` congenita: 8-)
/*
 * Restituisce la dimensione del buffer necessario
 * per contenere la stringa convertita.
 */
size_t converted_length(const char *s) {
   size_t len = 1; /* uno e` per il terminatore '\0' */
   for (; *s; s++)
      len += (*s == ' ' ? 3 : 1);
   return len;
}
/*
 * Converte gli " " in "%20"
 */
void convert(char *dst, const char *src) {
   for (; *src; src++)
      if (*src == ' ') {
         *(dst++) = '%';
         *(dst++) = '2';
         *(dst++) = '0';
      }
      else
         *(dst++) = *src;
   *dst = 0;
}
int main(void) {
   char *str = "Questa e` una stringa di prova.";
   char *buf;
   buf = malloc(converted_length(str));
   convert(buf, str);
   puts(buf);
   free(buf); /* liberi nella stesso scope dell'allocazione */
   return 0;
}
-- 
S.L.

 Ammira la mia illegibilita` congenita: 8-)
grazie anche a te, mi e' piaciuto molto il tuo modo di scrivere! :)
grazie a tutti quelli che mi hanno aiutato. ho risolto.


 [...]
S.L., piu' bello ancora:
size_t convert(const char *src, char* dst)
Se la chiami con
convert(src, NULL);
ritorna la dimensione della strunga una volta convertita, se la chiami con:
convert(src, dst);
converte e ritorna la dimensione della stringa convertita. C'e' solo una
piccola controindicazione... Alcune API Microsoft di Windows usano questa
tecnica :).
Luca