Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Puntatore a struct

14 views
Skip to first unread message

NERO23

unread,
May 11, 2013, 5:14:40 PM5/11/13
to
Per esercitarmi con le struct (sto studiando il C) ho scritto il codice
riportato sotto.

Cosa non va nel codice? Dopo aver inserito il nome, Codeblocks genera un
errore (per la precisione, va in crash...

Da un'analisi veloce, pare che il problema sia da attribuire alle righe
non le istruzioni scanf(....

Ciao
nero23


#include <stdio.h>

int main()
{
struct PIPPO
{
char *nome;
char *cognome;
int peso;
} elemento;

struct PIPPO *puntatore;
puntatore = &elemento;

printf("Inserisci il nome: ");
scanf("%s", puntatore->nome);

printf("Inserisci il cognome: ");
scanf("%s", puntatore->cognome);

printf("%s\n",puntatore->nome);
printf("%s\n",puntatore->cognome);

return 0;
}

enoquick

unread,
May 11, 2013, 6:49:27 PM5/11/13
to
Che nome e cognome non sono allocati

NERO23

unread,
May 12, 2013, 1:53:11 AM5/12/13
to

>
> Che nome e cognome non sono allocati
>


Forse mi sono perso qualcosa, ma perchᅵ devo allocare (presumo con
malloc? ) le variabili nome e cognome?

Se sostituisco le istruzioni di scanf... con

puntatore->nome="Mario";
puntatore->cognome"Rossi";

(quindi l'acquisizione del nome e del cognome ᅵ giᅵ assegnato)
tutto fila liscio...

ciao

NERO23

unread,
May 12, 2013, 2:32:23 AM5/12/13
to
Ho provato a cambiare la struct con questo codice:

struct PIPPO
{
char nome[20];
char cognome[20];
} elemento;

e sembra funzionare....

Ma cosᅵ il nome e il cognome sono limitati a 19 caratteri ed ᅵ ciᅵ che
non voglio...

Vincenzo Mercuri

unread,
May 12, 2013, 2:32:47 AM5/12/13
to
On 12/05/2013 07:53, NERO23 wrote:
[..]
> Se sostituisco le istruzioni di scanf... con
>
> puntatore->nome="Mario";
> puntatore->cognome"Rossi";
>
[..]

e insomma senza l'uguale non fila tutto liscio : )

--
Vincenzo Mercuri

NERO23

unread,
May 12, 2013, 2:45:04 AM5/12/13
to

>> puntatore->nome="Mario";
>> puntatore->cognome"Rossi";
>>
> [..]
>
> e insomma senza l'uguale non fila tutto liscio : )
>

ho risparmiato per effetto della crisi :)
ciao


Vincenzo Mercuri

unread,
May 12, 2013, 2:54:26 AM5/12/13
to
Certo che funziona, qui almeno hai un po' di spazio dove salvare
i caratteri che dai a scanf(), mentre a `char *nome' puoi dare solo
un valore, che ᅵ l'indirizzo di una locazione di memoria. Quando scrivi:

puntatore->nome = "Mario"

con la vecchia dichiarazione della struttura, di fatto scrivi:

puntatore->nome = &"Mario"[0];

cioᅵ l'indirizzo del primo carattere dello string literal "Mario",
e non hai spazio per nient'altro. Siccome devi inserire dei caratteri
a programma avviato, quindi in runtime, sarebbe piᅵ logico decidere
le dimensioni del tuo array di caratteri in runtime, quindi allocando
memoria dinamicamente. `scanf()' non ti permette di farlo. L'uso piᅵ
sicuro delle funzioni della famiglia 'scanf()' ᅵ se hai giᅵ una
sorgente e conosci giᅵ la formattazione dell'input, per esempio
se devi inserire caratteri in un array con 'sscanf()' ecc..
ma non conoscendo l'input a priori, nessuna ᅵ davvero sicura,
forse qualcuna lo ᅵ piᅵ di altre, ma..
Secondo me conviene scrivere una funzione di tipo "getline()", come
quella dello Standard POSIX che rialloca dinamicamente il buffer se
l'input ᅵ piᅵ grande del "previsto" (buffer allocato con `malloc()'
da te: http://man7.org/linux/man-pages/man3/getline.3.html
che inoltre restituisce il numero di caratteri letti.

--
Vincenzo Mercuri

Vincenzo Mercuri

unread,
May 12, 2013, 2:58:12 AM5/12/13
to
On 12/05/2013 08:54, Vincenzo Mercuri wrote:

[..] per esempio
> se devi inserire caratteri in un array con 'sscanf()' ecc..
[..]

Intendevo "leggere caratteri da un array", non inserire.

--
Vincenzo Mercuri

Archaeopterx

unread,
May 12, 2013, 3:01:55 AM5/12/13
to
Il 12/05/2013 08:32, NERO23 ha scritto:
> Ho provato a cambiare la struct con questo codice:
>
> struct PIPPO
> {
> char nome[20];
> char cognome[20];
> } elemento;
>
> e sembra funzionare....
>
> Ma così il nome e il cognome sono limitati a 19 caratteri ed è ciò che
> non voglio...
>

e allora fai qualcosa del genere; NON HO controllato il
codice e sicuramente è cannato, ma l'idea è quella di
avere un buffer di ampiezza sufficiente, leggere la
lunghezza della stringa e poi ricopiare dopo allocazione
dinamica. 1) Dovrai prenderti carico di disallocare quando
la memoria non ti serve più e comunque prima di terminare
2) Sicuramente il codice sotto è goffo 3) Ci saranno
sicuramente modi migliori.



int main ()
{
struct PIPPO
{
char *nome;
char *cognome;
int peso;
} elemento;

char buf[129] ;
int len ;
struct PIPPO *ptr ;

ptr = &elemento ;

printf("cognome?\n") ;
scanf("%s",buf) ;
/* leggi la lunghezza */
len = strlen (buf) ;
/* +1 per il carattere di terminazione */
(ptr->cognome) = malloc (len+1) ;
/* ora copi */
strcpy((ptr->cognome),buf) ;

/* prima di uscire */
free (ptr->cognome) ;
}

Vincenzo Mercuri

unread,
May 12, 2013, 3:12:46 AM5/12/13
to
On 12/05/2013 09:01, Archaeopterx wrote:
> Il 12/05/2013 08:32, NERO23 ha scritto:
[..]
> int main ()
> {
> struct PIPPO
> {
> char *nome;
> char *cognome;
> int peso;
> } elemento;
>
> char buf[129] ;
> int len ;
> struct PIPPO *ptr ;
>
> ptr = &elemento ;
>
> printf("cognome?\n") ;
> scanf("%s",buf) ;
> /* leggi la lunghezza */
> len = strlen (buf) ;
> /* +1 per il carattere di terminazione */
> (ptr->cognome) = malloc (len+1) ;
> /* ora copi */
> strcpy((ptr->cognome),buf) ;
>
> /* prima di uscire */
> free (ptr->cognome) ;
> }
>

Il punto non ᅵ solo che il programma ᅵ "cannato", ma non risolve..
qui usi comunque scanf(), ed ᅵ quello il problema :)

--
Vincenzo Mercuri

Archaeopterx

unread,
May 12, 2013, 3:31:08 AM5/12/13
to
Il 12/05/2013 09:12, Vincenzo Mercuri ha scritto:
>
> Il punto non è solo che il programma è "cannato", ma non risolve..
> qui usi comunque scanf(), ed è quello il problema :)
>

ops, vero!

enoquick

unread,
May 12, 2013, 9:31:55 AM5/12/13
to
Il 12/05/2013 01:32, NERO23 ha scritto:
> Ho provato a cambiare la struct con questo codice:
>
> struct PIPPO
> {
> char nome[20];
> char cognome[20];
> } elemento;
>
> e sembra funzionare....
>

Inizia a chiederti perchè cosi funziona

> Ma così il nome e il cognome sono limitati a 19 caratteri ed è ciò che
> non voglio...
>

Di quanto li vorresti ?



NERO23

unread,
May 12, 2013, 12:27:37 PM5/12/13
to
Su un corso di programmazione online (c++) ho visto questo codice:


#include <stdio.h>
struct Card
{
char *nome;
char *cognome;
};
int main(void)
{

struct Card ppp;

ppp.nome = "Vincenzo";
ppp.cognome = "Biello";

}



In questo esempio, la funzione di scanf non serve perchᅵ il nome e il
cognome viene inserito direttamente da codice. Se ho capito bene quanto
scritto da voi, il problema di allocazione non rimane anche in questo
esempio?

Archaeopterx

unread,
May 12, 2013, 1:52:40 PM5/12/13
to
Il 12/05/2013 18:27, NERO23 ha scritto:
> Su un corso di programmazione online (c++) ho visto
> questo codice:
>
>
> #include <stdio.h> struct Card { char *nome; char
> *cognome; }; int main(void) {
>
> struct Card ppp;
>
> ppp.nome = "Vincenzo"; ppp.cognome = "Biello";
>
> }
>
>
>
> In questo esempio, la funzione di scanf non serve
> perchè il nome e il cognome viene inserito
> direttamente da codice. Se ho capito bene quanto
> scritto da voi, il problema di allocazione non rimane
> anche in questo esempio?

Il problema non c'è perché la lunghezza delle stringhe è
nota e costante, e il compilatore può riservare la memoria
necessaria.

0 new messages