Newsgroup: it.comp.lang.c
Titolo: Strutture e stringhe

Ciao,
sto facendo amicizia con le strutture e i puntatori a queste.
Sotto un programmino di cui ho evidenziato gli errori che non riesco a 
capire, specie i primi 2 (che poi sono lo stesso errore).
Grazie mille
 
#include <stdio.h>
 
#define MAXS 100
#define MAXA 200
 
typedef enum {
	HOBBY, AUTO, CASA, SPORT
} Categoria;
 
typedef struct {
	Categoria cat;
	float prezzo;
	char descr[MAXS];
} Annuncio;
 
typedef struct {
	Annuncio ann[MAXA];
	int numAnn;
} ArchivioAnn;
 
int main () {
	ArchivioAnn arch;
	ArchivioAnn *p;	
	Annuncio A;	
	p=&arch;
	A.descr="Usato";     //ERRORE
	p->ann[0].descr="nuovo"; //Errore
	scanf("%s",A.descr); // OK
	p->ann[0].cat=AUTO;  //OK
	scanf("%d",p->ann[0].cat); //warning, ma eseguito restituisce Errore di 
Segmentazione	
	return 0;	
}
 
*Output gcc*
 
prova1.c: In function ‘main’:
prova1.c:26:9: error: incompatible types when assigning to type 
‘char[100]’ from type ‘char *’
   A.descr="Usato";     //ERRORE
          ^
prova1.c:27:17: error: incompatible types when assigning to type 
‘char[100]’ from type ‘char *’
   p->ann[0].descr="nuovo"; //Errore
                  ^
prova1.c:30:2: warning: format ‘%d’ expects argument of type ‘int *’, 
but argument 2 has type ‘unsigned int’ [-Wformat=]
   scanf("%d",p->ann[0].cat); //warning, ma eseguito restituisce Errore 
di Segmentazione
   ^
 
---
Questa e-mail è stata controllata per individuare virus con Avast antivirus.
https://www.avast.com/antivirus
 
 

    ^
 
vai a leggere come funziona scanf(), gli argomenti dopo il "" devono essere puntatori, la prima scanf() che usi non ti da' errore per caso.
 
Ciao Jack

    ^
 
Leggi attentamente il warning: ti dice proprio quale errore stai
commettendo: lui si aspetta un puntatore a intero mentre tu
gli passi un intero. Per ragioni storiche il C e' poco schizzinoso
e genera un warning ma quello che accade a run time e' che il
valore intero viene interpretato come un indirizzo di memoria
(il puntatore) e quindi punta a zone di memoria casuali che
poi ti danno il segmentation error.
Per risolvere, passagli &(p->ann[0].cat)
 
ciao
Giacomo

 Per risolvere, passagli &(p->ann[0].cat)
 
grazie ad entrambi, l'errore sulla stringa l'ho capito.
 
Capito anche che a scanf 8per l' enum) devo passare un puntatore al tipo 
che si aspetta (int in questo caso), però non so come risolvere.
Applicando la soluzione suggerita &(p->ann[0].cat) mi restituisce sempre 
errore perchè in effetti la scanf si aspetta un puntatore a int, mentre 
io le sto passando un puntatore a enum, gcc mi dice "argument 2 has type 
'enum Categoria *'"
 
Forse la scanf non è idonea ad acquisire un enum da tastiera?
Grazie ciao


 Forse la scanf non è idonea ad acquisire un enum da tastiera?
 
risolto sostituendo il formato %d con %u nella scanf. Mi sembra una 
questione di schizzinosità o sbaglio?
Anche perchè se metto %d mi da Errore di segmentazione se eseguo il 
programma.
Ciao


'enum Categoria *'"
 
E' solo un pochetto schizzinoso, dagli in pasto (int*)&(p->ann[0].cat)
e dovrebbe calmarsi. Non c'e' bisogno di mettere "%u", anzi e' errato,
perche' gli enum sono interpretati come int (salvo casi particolari ma
non e' il tuo).
-- 
andrea - ri mi cci, name

>> Forse la scanf non è idonea ad acquisire un enum da tastiera?
Attenzione: in tastiera devi mettere il NUMERO assegnato al tuo enum,
non la stringa che lo rappresenta.
 
Tra l'altro, vedo che non li hai assegnati in dichiarazione.
 
Se fosse:
 
typedef enum {
	HOBBY=0, AUTO=1, CASA=2, SPORT=3
} Categoria;
 
 
E in tastiera scrivi 3 (che sarebbe SPORT), dovrebbe funzionare.


 e dovrebbe calmarsi.
 
grazie!!! questo è sicuramente concettualmente corretto


 la funzione strcpy() 
 
Non e` del tutto esatto. Puoi farlo solo se stai assegnando:
 
char a[] = "pippo";


Quello non e' un assegnamento ma una dichiarazione con inizializzazione
 

 Quello non e' un assegnamento ma una dichiarazione con inizializzazione
 
Puntualizzazione stupida. Una inizializzazione *assegna* quel valore ad un'area di memoria. Il punto vero e` che in un'inizializzazione con un literal, il nome dell'array NON decade a puntatore al primo elemento.
 
 
 


Arrampicata sugli specchi
Vedila come vuoi,ma ti consiglio di studiare (il C)
Ed in C (e C++) non si puo assegnare un array primitivo per copia
Al massimo si possono copiare i puntatori vedendo l'array come puntatore 
al primo elemento ma non e' la stessa cosa.
 
int a; // dichiarazione (il valore e' indefinito)
int a=5; // dichiarazione con inizializzazione;
a=5; // assegnamento
 
 
riprova con gli array
 
 

On 20/09/2016 00:07, enoquick wrote:
 
[...]
LOL :) Tu che consigli di studiare il C e` veramente il colmo, visto le 
figuracce che hai appena fatto altrove. Io non ho bisogno di 
arrampicarmi sugli specchi, e tantomeno con un idiota come te, enoquick. 
Io sto parlando di inizializzazione di un array con un literal stringa, 
operazione del tutto lecita in C. Nell'inizializzazione con un literal 
stringa, il nome dell'array non decade in puntatore al suo primo 
elemento. Sei tu che devi studiarti il C. Il codice che ho scritto nel 
mio messaggio precedente e` chiaro.
 
-- 
4ndre4


 
Sei tu,bene
Avrei dovuto capirlo prima
 
Ma veniamo a noi:
 
 >>>> il testo qui sotto lo hai scritto tu
Non e` del tutto esatto. Puoi farlo solo se stai assegnando:
 
char a[] = "pippo";
 
 >>>>>> fine
 
 
Ti sembra una assegnazione ?
 
Dopo questa (per i soliti insulti,non per l'errore tuo commesso) puoi 
andare nel killfile anche qui
 
 

Imbecille, io non ho commesso nessun errore. Io sto proprio parlando di un'inizializzazione, come spiegato più e più volte. Il tuo kill file ficcatelo al culo.