Linguaggio C, warning utilizzando %s e struct di array

di il
17 risposte

Linguaggio C, warning utilizzando %s e struct di array


#include <stdio.h>
#include <string.h>

#define M_MAX 5

struct studente
{
  	int matricola;
	char *nome;
	char *cognome;
};

int main()
{
	struct studente M[DIM_M];
	int n, i;
	
	printf("\n\tRegistro attivita' studenti \n\tInserimento dati matricole \n\tNumero studenti? ");
	scanf("%d", &n);	
	
	//Inserimento dati all'interno della struttura
	for(i = 0; i < n; i++)
	{
		printf("\n\n\tInserimento %d\n", i);
		printf("\tMatricola: "); scanf("%d\n", &M[i].matricola);
		printf("\tNome: "); scanf("%s \n", &M[i].nome);
		printf("\tCognome: "); scanf("%s \n", &M[i].cognome);
	}

}
Compilando mi dice:

main.c:18:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
printf("\tNome: "); scanf("%s \n", &M.nome);
^
main.c:19:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
printf("\tCognome: "); scanf("%s \n", &M.cognome);
^


Perché?

17 Risposte

  • Re: Linguaggio C, warning utilizzando %s e struct di array

    M.nome è già di suo un char *
    di conseguenza &M.nome è un char **
    Comunque ti sconsiglio di utilizzare scanf(), molto meglio fgets() di cui trovi innumerevoli esempi e discussioni in questo stesso forum.
    p.s. dai una dimensione alle stringhe, non semplicemente char *, altrimenti da qualche parte le devi allocare!!!
  • Re: Linguaggio C, warning utilizzando %s e struct di array

    struct studente
    {
    	int matricola;
    	char nome[40];
    	char cognome[50];
    };
    
    Così mi dice:

    main.c:18:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[40]’ [-Wformat=]
    printf("\tNome: "); scanf("%s \n", &M.nome);
    ^
    main.c:19:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[50]’ [-Wformat=]
    printf("\tCognome: "); scanf("%s \n", &M.cognome);
    ^

    E, sempre con questa struct, con printf("\tNome: "); fgets(M.nome); mi dice:

    main.c:18:3: error: too few arguments to function ‘fgets’
    printf("\tNome: "); fgets(M.nome);//scanf("%s \n", &M.nome);
    ^
    In file included from definizioni.h:17:0,
    from main.c:1:
    /usr/include/stdio.h:622:14: note: declared here
    extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
    ^
    make: *** [exe] Errore 1


    Come posso fare?
  • Re: Linguaggio C, warning utilizzando %s e struct di array

    Come posso fare?
    Per quanto riguarda la fgets() cerca con google come richiamare questa funzione.
  • Re: Linguaggio C, warning utilizzando %s e struct di array

    Ho letto tutto attentamente, e ho provato anche a fare quello che mi hai detto tu. Mi da sempre lo stesso problema!
  • Re: Linguaggio C, warning utilizzando %s e struct di array

  • Re: Linguaggio C, warning utilizzando %s e struct di array

    Ho provato a fare come scritto su questo sito:

    http://www.daniweb.com/software-development/c/threads/112772/using-fgets-properly

    Ovvero:
    fflush(stdin);
    fgets(M[i].nome, sizeof M[i].nome, stdin);
    Compilando non mi da errori, però quando lo eseguo non me lo fa inserire. Si blocca subito dopo l'inserimento della matricola.

    Se lo volessi fare con scanf, altrimenti, come dovrei fare?
  • Re: Linguaggio C, warning utilizzando %s e struct di array

    Devi eliminare tutti i \n dalle scanf
  • Re: Linguaggio C, warning utilizzando %s e struct di array

    Oh, bene! Ora me li fa inserire. Grazie!! Però mi da sempre questo warning:

    main.c: In function ‘main’:
    main.c:22:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
    printf("\tNome: "); scanf("%s", &M.nome);
    ^


    Non c'è un modo per toglierlo?
  • Re: Linguaggio C, warning utilizzando %s e struct di array

    Più che cercare un modo per "toglierlo" dovresti capirlo ...

    M.nome è già un puntatore a carattere (un char *) che è quello che si aspetta la scanf.
    Se scrivi &M.nome allora diventa un puntatore a puntatore (un char **) e NON va bene.

    Questo significa che, dopo tantissimi post e tanto studio del C, ancora non hai capito molto dei puntatori ...
  • Re: Linguaggio C, warning utilizzando %s e struct di array

    Evidentemente no, ma è per questo che faccio gli esercizi
  • Re: Linguaggio C, warning utilizzando %s e struct di array

    La mia non era una critica "fine a sé stessa" ... non mi permetterei ... era per evidenziare il fatto che devi fare un numero maggiore di esercizi sui puntatori.

    Non devi fare "grandi esercizi" o "esercizi molto complessi" ...

    Devi esercitarti sui puntatori con esempi di poche linee, tanti esempi diversi da 3 o 4 linee che trattino tutti gli aspetti principali dei puntatori.

    Ad esempio, il fatto che tu abbia inizialmente inserito

    char *nome;
    char *cognome;

    nella struttura e li abbia usati direttamente - senza allocare lo spazio - vuol dire che devi soffermarti ancora sul significato di puntatore, insomma le basi.
  • Re: Linguaggio C, warning utilizzando %s e struct di array

    Nemmeno io volevo criticare, tranquillo. Va bene seguirò il tuo consiglio, ti ringrazio.

    Solo ti sarei grato se mi dicessi il motivo dell'ultimo warning.

  • Re: Linguaggio C, warning utilizzando %s e struct di array

    Solo ti sarei grato se mi dicessi il motivo dell'ultimo warning.
    Ti è già stato spiegato, sia da me che da oregon.
    M.nome è una stringa C, una puntatore a char ovvero char *.
    Il compilatore ti dice che "format ‘%s’ expects argument of type ‘char *", ovvero che se usi %s devi successivamente specificare un char *, una stringa C, nel tuo caso M.nome.
    Perchè hai aggiunto &? Se passi &M.nome stai passando un char **.
    Prova a rifletterci sopra; se invece ti interessa solo la soluzione semplicemente togli &.
  • Re: Linguaggio C, warning utilizzando %s e struct di array

    davide.fruci ha scritto:


    Solo ti sarei grato se mi dicessi il motivo dell'ultimo warning.
    Ma non te l'ho già detto?
Devi accedere o registrarti per scrivere nel forum
17 risposte