View Full Version : [c] grossi dubbi con le stringhe
ho un po di problemi con le stringhe in c:
1. perchè se scrivo
char prova[5]={"ciao"}; funziona ma se scrivo:
char prova[5];
prova="ciao"; oppure prova={"ciao"}; non va???
in piu ho notato che scrivendo
char *prova[5];
prova="ciao"; funziona, ma per quale motivo?
2. ho una struct del tipo:
struct prova{ char stringa[5]};
struct prova struttura;
struttura.stringa="ciao"; e non funziona quest'ultima riga, come faccio?
vi sarei davvero grato di una mano! In sostanza come posso modificare una stringa dopo l'inizializzazione?
royaleagle
20-11-2008, 23:47
Non funziona perchè prova (nel punto 1) e stringa (nel punto 2) sono puntatori al primo elemento dei rispettivi array, che sono array di char.
Quindi tu invece assegni una stringa ad un char.
1. "Ciao" è un cosiddetto literal constant. Di fatto è un stringa che è allocata in memoria al momento della creazione del programma. Ha quindi una sua allocazione ed una sua posizione in memoria.
char *p = "Ciao";
assegna al puntatore p l'indirizzo del literal constant.
{"Ciao"} o "Ciao" si possono usare per inizializzare le stringhe...ma SOLO in fase di inizializzazione.
Infatti se io scrivo:
char x[5];
x = "ciao";
è un errore perché x ha un puntatore predefinito durante l'inizializzazione e NON MODIFICABILE. Quindi è impossibile modifcare x assegnandogli il puntatore a literal constant.
2. Per modificare il valore di una stringa si usa la funzione di libreria strcpy.
1. "Ciao" è un cosiddetto literal constant. Di fatto è un stringa che è allocata in memoria al momento della creazione del programma. Ha quindi una sua allocazione ed una sua posizione in memoria.
char *p = "Ciao";
assegna al puntatore p l'indirizzo del literal constant.
{"Ciao"} o "Ciao" si possono usare per inizializzare le stringhe...ma SOLO in fase di inizializzazione.
Infatti se io scrivo:
char x[5];
x = "ciao";
è un errore perché x ha un puntatore predefinito durante l'inizializzazione e NON MODIFICABILE. Quindi è impossibile modifcare x assegnandogli il puntatore a literal constant.
2. Per modificare il valore di una stringa si usa la funzione di libreria strcpy.
grazie mille, quindi se scrivo
char*prova;
*prova="ciao";
funziona perchè vado ad agire sul contenuro dell'indirizzo puntato giusto?
quindi senza le function della libreria string è praticamente impossibile lavorare bene con le stringhe no?
banryu79
21-11-2008, 13:37
quindi senza le function della libreria string è praticamente impossibile lavorare bene con le stringhe no?
No, puoi lavorarci lo stesso, ma in pratica ciò significa andare a implementarsi le stesse funzionalità che quella libreria espone.
royaleagle
21-11-2008, 13:52
grazie mille, quindi se scrivo
char*prova;
*prova="ciao";
funziona perchè vado ad agire sul contenuro dell'indirizzo puntato giusto?
No, devi scrivere:
char*prova;
prova="ciao";
No, devi scrivere:
char*prova;
prova="ciao";
E' legale, ma attenzione...è rischioso perché questo provoca un errore:
char *prova;
prova = "ciao";
prova[1] = 'b'; <------è errato perché si va a modificare un literal constant
Non so in C, ma in C++ prova = "ciao" genera uno warning:
/home/cionci/provacpp/prova.cpp|163|warning: deprecated conversion from string constant to ‘char*’|
Al contrario questo non lo genera su prova = "ciao", ma viene segnalato un errore sulla riga succesiva:
const char *prova;
prova = "ciao";
prova[1] = 'b'; <------errore
ok ora è tutto un poco più chiaro! sono alle prese col c da qualche mese, prima avevo studiato java e pascal, trovo che una delle "pecche" maggiori del c sia la mancanza di una variabile di tipo string, che renderebbe la risoluzione di molti problemi piu semplici, non trovate anche voi?
Vincenzo1968
21-11-2008, 17:11
ok ora è tutto un poco più chiaro! sono alle prese col c da qualche mese, prima avevo studiato java e pascal, trovo che una delle "pecche" maggiori del c sia la mancanza di una variabile di tipo string, che renderebbe la risoluzione di molti problemi piu semplici, non trovate anche voi?
Più semplice ma meno performante. È il rovescio della medaglia :bimbo:
x Cionci : :tie:
banryu79
21-11-2008, 17:15
Più semplice ma meno performante. È il rovescio della medaglia :bimbo:
x Cionci : :tie:
C'avrei giurato :asd:
Vincenzo1968
21-11-2008, 17:18
C'avrei giurato :asd:
Ohé banryu,
sto sperimentando delle faccine che non avevo mai utilizzato e che mi piacciono un sacco. Perciò tie': :tie:
:bimbo:
:D
banryu79
21-11-2008, 17:20
Allora buon week end :fuck:, lol
Alex_87_xelA
22-11-2008, 15:32
ho un po di problemi con le stringhe in c:
1. perchè se scrivo
char prova[5]={"ciao"}; funziona ma se scrivo:
char prova[5];
prova="ciao"; oppure prova={"ciao"}; non va???
char prova[5] = "ciao";
analizziamo da destra a sinistra :
-"ciao"
questo non fa altro che creare una stringa costante (const char *)
-char prova[5]
questo crea un vettore di 5 elementi di tipo char;
come è gestito un vettore : un vettore è gestito come un puntatore costante al primo elemento, infatti utilizzando il suo nome (nel tuo caso - prova) non fai altro che utilizzare l'indirizzo della prima locazione di memoria puntata da tale variabile.
come si gestiscono i puntatori costanti, devono essere subito inizzializzati all'atto della dichiarazione, quindi bisogna definirli subito.
ecco perchè nel primo caso funziona.
poi nel secondo caso, come detto, essendo un puntatore costante, non puo essere riassegnato.
in piu ho notato che scrivendo
char *prova[5];
prova="ciao"; funziona, ma per quale motivo?
prova = "ciao"; NON funziona
per farlo funzionare dovresti fare :
*prova = "ciao";
2. ho una struct del tipo:
struct prova{ char stringa[5]};
struct prova struttura;
struttura.stringa="ciao"; e non funziona quest'ultima riga, come faccio?
il motivo è lo stesso che ti ho spiegato prima
vi sarei davvero grato di una mano! In sostanza come posso modificare una stringa dopo l'inizializzazione?
//sd = stringa destinazione
//so = stringa origina
char *CopiaStringa(char *sd, const char *so)
{
char *temp = sd;
while(*sd++ = *so++) ;
return sd;
}
Alex_87_xelA
22-11-2008, 15:49
E' legale, ma attenzione...è rischioso perché questo provoca un errore:
scusa, ma se da un'errore allora non è legale .... no ?
scusa, ma se da un'errore allora non è legale .... no ?
La modifica della stringa provoca un errore, non l'assegnazione.
Alex_87_xelA
22-11-2008, 15:55
char *prova;
prova = "ciao";
prova[1] = 'b'; <------è errato perché si va a modificare un literal constant
prova = "ciao"; <----- questo è un'errore
proca[1] = 'b'; <------ questo non è un'errore in questo caso.
era un'errore se si aveva :
const char *prova;
scusa, ma se da un'errore allora non è legale .... no ?
La modifica della stringa provoca un errore, non l'assegnazione.
L'assegnazione di un literal constant provoca uno warning che l'assegnamento è deprecato. Il fatto che sia deprecata non significa che sia illegale, è legale, ma deprecata.
prova = "ciao"; <----- questo è un'errore
proca[1] = 'b'; <------ questo non è un'errore in questo caso.
era un'errore se si aveva :
const char *prova;
No, l'errore è la modifica tramite prova, visto che prova punta ad un literal constant. Se non si usa quel puntatore per modificare il literal costant allora non si avranno problemi ed il codice continuerà a funzionare. Leggi gli errori, non me li sono inventati, li ha scritti il compilatore.
Se invece si va a fare una modifica tramite il puntatore il codice provocherà un segmentation fault a runtime.
Alex_87_xelA
22-11-2008, 16:04
Se invece si va a fare una modifica tramite il puntatore il codice provocherà un segmentation fault a runtime.
ho appena provato e hai ragione
ero andato un po a ricordi
Alex_87_xelA
22-11-2008, 16:17
No, l'errore è la modifica tramite prova, visto che prova punta ad un literal constant. Se non si usa quel puntatore per modificare il literal costant allora non si avranno problemi ed il codice continuerà a funzionare. Leggi gli errori, non me li sono inventati, li ha scritti il compilatore.
Se invece si va a fare una modifica tramite il puntatore il codice provocherà un segmentation fault a runtime.
vedi se ricordo bene !!!
char *prova;
prova = "alex";
fin qui tutto bene ... ora ...
"alex" genera in memoria gli indirizzi delle singole lettere in modo consecutivo giusto ?
quindi se vado a modificare ad esempio il 2° elemento
prova[1] = 'x';
vado a modificare si il 2° elemento, ma quindi anche il suo indirizzo. (con quello della nuova lettera)
quindi non avro piu indirizzi contigui ma sfasati.
per questo si genera un'errore no ?
In quel modo non vai a modificare l'indirizzo del secondo elemento, vai solamente a cambiarne il valore.
I literal per definizione devono essere costanti, quindi si genera un errore perché di fatto il puntatore al literal è un puntatore di tipo const char *.
Questa cosa può essere implementata in molti modi dal compilatore, ad esempio allocando tutti i literal all'interno di una pagina di memoria che ha settato il flag di sola lettura.
Alex_87_xelA
22-11-2008, 16:28
In quel modo non vai a modificare l'indirizzo del secondo elemento, vai solamente a cambiarne il valore.
I literal per definizione devono essere costanti, quindi si genera un errore perché di fatto il puntatore al literal è un puntatore di tipo const char *.
Questa cosa può essere implementata in molti modi dal compilatore, ad esempio allocando tutti i literal all'interno di una pagina di memoria che ha settato il flag di sola lettura.
hai ragione, sarà che mi sono svegliato da poco che sto sparando una marea di .......
:muro:
grazie per la spiegazione
Alex_87_xelA
22-11-2008, 16:33
In quel modo non vai a modificare l'indirizzo del secondo elemento, vai solamente a cambiarne il valore.
I literal per definizione devono essere costanti, quindi si genera un errore perché di fatto il puntatore al literal è un puntatore di tipo const char *.
Questa cosa può essere implementata in molti modi dal compilatore, ad esempio allocando tutti i literal all'interno di una pagina di memoria che ha settato il flag di sola lettura.
quindi se abbiamo :
char *prova;
prova = "alex";
come faccio a cambiare ad esempio il 2° elemento della stringa.
devo perforza creare un'altra stringa con la modifica fatta e assegnarla al puntatore ?
Non puoi andare a modificare quell'area di memoria, devi agire in maniera indiretta.
char * prova2 = (char *) malloc(strlen(prova));
strcpy(prova2, prova);
prova = prova2;
//ora la posso modificare
Alex_87_xelA
22-11-2008, 16:44
Non puoi andare a modificare quell'area di memoria, devi agire in maniera indiretta.
char * prova2 = (char *) malloc(strlen(prova));
strcpy(prova2, prova);
prova = prova2;
//ora la posso modificare
quindi avevo pensato bene.
(va bhe era un po contorta come l'avevo detta, ma il concetto era quello)
grazie :D
Avevo già fatto un errore :D :eek:
char * prova2 = (char *) malloc(strlen(prova) + 1);
Alex_87_xelA
22-11-2008, 16:50
Avevo già fatto un errore :D :eek:
char * prova2 = (char *) malloc(strlen(prova) + 1);
hai ragione non ci avevo nemmeno fatto caso
per lo '\0' già già
:nonsifa:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.