Newsgroup: it.comp.lang.c
Titolo: passaggio stringhe per riferimento

salve,
sono un dilettante di C e vorrei sapere come fare a passare una "stringa"
per riferimento in modo cioè che le modifiche fatte nella
funzione chiamata, modifichino l'originale passata dall'esterno.
Usando char str[] come var da passare e come argomento riesco, ma volendolo
fare come puntatori non riesco.
Per gli int ho letto che basta una cosa del genere
int y = 5;
funz(&y);
.....
void funz(int* param)
ma con le stringhe ottengo warning di assegnamenti anomali
Grazie

 ma con le stringhe ottengo warning di assegnamenti anomali
Dovresti postare il tuo codice. Comunque questo e` un esempio:
#include <stdio.h>
void modify_string(char *s)
{
     /* Cambia il primo carattere della stringa */
     s[0] = 'M'; /* Oppure *s = 'M'; */
}
int main(void)
{
     char s[] = "Ciao";
     puts(s);
     modify_string(s);
     puts(s);
     return 0;
}
Il nome s "decade" (in quasi tutti i contesti) in un puntatore al primo 
elemento dell'array, quindi il tipo del parametro ricevuto coincide.
Nota inoltre che i prototipi:
     void modify_string(char *s)
     void modify_string(char s[])
sono esattamente equivalenti: entrambi indicano che s e` un puntatore a 
char (si tratta di un'inconsistenza della sintassi del C).
-- 
Enrico `Trippo' Porreca

 char (si tratta di un'inconsistenza della sintassi del C).
E quello che ho sempre pensato anche io, e infatti mi stupisco dei problemi
che sto incontrando.
Adesso scrivo degli esempini chiari di cio che cerco di fare e soprattutto
dei warning che ottengo
usando le varie forme char[] o char*.
Grazie...... e rimani "sintonizzato" su questo thread...please ;-)


Ecco qua gli esempi:
1 SRC: orig
void mia(char* str) {
 printf("\nstr PRIMA: %s - %p %p", str, str, &str);
 str = "mmmmm";
 printf("\nstr DOPO: %s - %p %p", str, str, &str);
}
int main(int argc, char* argv[]) {
 char* x = "aaaa";
 printf("\nPRIMA x: %s - %p %p", x, x, &x);
 mia(x);
 printf("\nDOPO x: %s - %p %p \n", x, x, &x);
 exit(99);
COMPILA: OK
ESEC:
PRIMA x: aaaa - 0x8048ef3 0xbffff784
str PRIMA: aaaa - 0x8048ef3 0xbffff760
str DOPO: mmmmm - 0x8048ed7 0xbffff760
DOPO x: aaaa - 0x8048ef3 0xbffff784
----------------------------------------------------------
2 SRC: (modifiche dal primo):DA  str = "mmmmm";  A  *str = "mmmmm";
void mia(char* str) {
 printf("\nstr PRIMA: %s - %p %p", str, str, &str);
 *str = "mmmmm";
 printf("\nstr DOPO: %s - %p %p", str, str, &str);
}
int main(int argc, char* argv[]) {
 char* x = "aaaa";
 printf("\nPRIMA x: %s - %p %p", x, x, &x);
 mia(x);
 printf("\nDOPO x: %s - %p %p \n", x, x, &x);
 exit(99);
COMPILA:
Client.c: In function `mia':
Client.c:20: warning: assignment makes integer from pointer without a cast
ESEC:
PRIMA x: aaaa - 0x8048ef3 0xbffff784
Segmentation fault
-------------------------------------------------------------
3 SRC: modifiche da primo: DA mia(x);  A  mia(&x);
void mia(char* str) {
 printf("\nstr PRIMA: %s - %p %p", str, str, &str);
 str = "mmmmm";
 printf("\nstr DOPO: %s - %p %p", str, str, &str);
}
int main(int argc, char* argv[]) {
 char* x = "aaaa";
 printf("\nPRIMA x: %s - %p %p", x, x, &x);
 mia(&x);
 printf("\nDOPO x: %s - %p %p \n", x, x, &x);
 exit(99);
COMPILA:
Client.c: In function `main':
Client.c:27: warning: passing arg 1 of `mia' from incompatible pointer type
ESEC:
PRIMA x: aaaa - 0x8048ef3 0xbffff784
str PRIMA: 卷獨|@ - 0xbffff784 0xbffff760
str DOPO: mmmmm - 0x8048ed7 0xbffff760
DOPO x: aaaa - 0x8048ef3 0xbffff784
----------------------------------------------------------------------------
4 SRC: CON ARRAY
void mia(char str[]) {
 printf("\nstr PRIMA: %s - %p %p", str, str, &str);
 str = "mmmmm";
 printf("\nstr DOPO: %s - %p %p", str, str, &str);
}
int main(int argc, char* argv[]) {
 char x[] = "aaaa";
 printf("\nPRIMA x: %s - %p %p", x, x, &x);
 mia(x);
 printf("\nDOPO x: %s - %p %p \n", x, x, &x);
 exit(99);
COMPILA: OK
ESEC:
PRIMA x: aaaa - 0xbffff770 0xbffff770
str PRIMA: aaaa - 0xbffff770 0xbffff750
str DOPO: mmmmm - 0x8048ef7 0xbffff750
DOPO x: aaaa - 0xbffff770 0xbffff770
---------------------------------------------
5 SRC: CON ARRAY FUNZIONA MA DEVO CAMBIARE CARATTERE CARATTERE!!!
void mia(char str[]) {
 printf("\nstr PRIMA: %s - %p %p", str, str, &str);
 str[0] = 'm';
 str[1] = 'n';
 printf("\nstr DOPO: %s - %p %p", str, str, &str);
}
int main(int argc, char* argv[]) {
 char x[] = "aaaa";
 printf("\nPRIMA x: %s - %p %p", x, x, &x);
 mia(x);
 printf("\nDOPO x: %s - %p %p \n", x, x, &x);
 exit(99);
COMPILA: OK
ESEC:
PRIMA x: aaaa - 0xbffff770 0xbffff770
str PRIMA: aaaa - 0xbffff770 0xbffff750
str DOPO: mnaa - 0xbffff770 0xbffff750
DOPO x: mnaa - 0xbffff770 0xbffff770
Come posso ottenere l'effetto di "Modifica dell'originale" come accade in 5
ma sfruttando char* invece che char[] e potendo modificare l'intera stringa
e non carattere carattere
GRAZIE

 5 ma sfruttando char*
Innanzitutto, i letterali stringa non sono modificabili. E' possibile 
assegnare l'indirizzo di un letterale a una variabile 'char*' (anziché 
'const char*'), ma se tenti di usare quel puntatore per modificare il 
letterale ottieni effetti indefiniti (ad es: 'Segmentation fault').
In secondo luogo, se 'x' č una variabile di tipo 'char*', '&x' denota 
l'indirizzo di quella variabile, che non ha nulla a che vedere con 
l'indirizzo dell'array di caratteri che vorresti modificare ("warning: 
passing arg 1 of `mia' from incompatible pointer type").
Max

 e non carattere carattere
L'"intera stringa" è un array di caratteri: cambiarla vuol dire cambiare i
caratteri.
Ma forse tu volevi fare qualcosa di questo genere:
void mia (char ** pstr)
{
    printf("\npstr PRIMA: %s - %p %p", *pstr, *pstr, pstr);
    *pstr = "mmmmm";
    printf("\npstr DOPO: %s - %p %p", *pstr, *pstr, pstr);
}
int main(int argc, char* argv[])
{
    char * x = "aaaa";
    printf("\nPRIMA x: %s - %p %p", x, x, &x);
    mia(&x);
    printf("\nDOPO x: %s - %p %p \n", x, x, &x);
 }
In questo caso, mia() prende un puntatore alla VARIABILE x (che è a sua
volta un puntatore a carattere). Quando fai così:
    *pstr = "mmmmm";
è come se tu facesi così:
    x = "mmmmm";
--
Cingar
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

era proprio quello che cercavo, anche se purtroppo giurerei di averlo già
provato
e di aver visto sulla stringa del main (la x intendo) dei simboli
strani/casuali come valore.
Cmq ho appena testato il tuo esempio su Win (Dev-C++ di bloodshed) ed è
proprio
quello che volevo, ora riprovo su Linux (Mandrake 9.2) con il "cc"...
Domandina (in attesa della riprova): non riesco a far funzionare la "strcpy"
con un puntatore char*
ma solo con char[], mi potresti fare un esempio (ammesso che si possa fare)
Grazie 1000


 fare)
 char array[] = "foo";    /* array  di char */
 strcpy( array, "bar" );  /* OK */
 char* wp = array;        /* 'wp' punta ad un array scrivibile */
 strcpy( wp, "bar" );     /* OK */
 char* nwp = "foo";       /* 'nwp' punta ad un array NON scrivibile */
 strcpy( nwp, "bar" );    /* compila, ma ha comportamento indefinito! */
 const char* nwp2 = "foo";
 strcpy( nwp2, "bar" );   /* NON compila perché strcpy vuole un 'char*' */
Max

 (ammesso che si possa fare)
Boh, non so bene di che parli, anche perché la strcpy di argomenti ne ha
due...
Il primo argomento è di tipo (char *), quindi devi passare l'indirizzo di un
tuo VARIABILE di tipo array di caratteri (char []), e questo array deve
essere grande abbastanza per contenere ciò che ci vuoi mettere.
Il secondo argomento è di tipo (const char *): quel const significa che la
funzione non vuole (e non può) modificare l'array che le passi, per cui
questo secondo argomente può essere quel cavolo che vuoi.
Esempio valido:
    char s [100] = "UNO";
    strcpy(s, "e DUE!");
Esempio di baggianata:
    char * s = "UNO";
    strcpy(s, "e DUE!");
    /*
    BOOM! Errore run-time perché:
    1) Stai cercando di scrivere dentro un array costante;
    2) Stai cercando di copiare un array da 6 byte in uno che è lungo solo 4!
    */
È più facile rendersi conto dell'errore se tieni a mente che tutte le
cosiddette "costanti stringa" sono in realtà della variabili nascoste di
tipo (static const char []). Il codice sopra viene trasformato dal
compilatore più o meno così:
    static const char _Stringa_1 [4] = { 'U', 'N', 'O', '\0' };
    static const char _Stringa_2 [6] = { 'e', 'D', 'U', 'E', '!', '\0' };
    char * s = _Stringa_1;
    strcpy(s, _Stringa_2);
    /* Stai copiando _Stringa_2 (che ha 6 byte) dentro
    _Stringa_1 (che ha solo 4 byte ed è pure READ ONLY). */


 ha scritto nel messaggio
news:195Z223Z37Z55Y...@usenet.libero.it...
