2010-12-11 13 views
37

Voglio rimuovere l'avvertimento che ottengo su questa linea del codice,avvertimento: non formato una stringa letterale e senza argomenti formato

FILE *fil; 
char *imp; 
(...) 
fprintf(fil,imp); 

la cosa è quando faccio questo scrive sul file esattamente quello che voglio, ma se applico il formato% s non è così, in questo modo

fprintf(fil, "%s", imp); 
+0

Cosa significa 'imp' contiene? – casablanca

+1

Cosa succede se si sostituisce fprintf con 'fputs (imp, fil);'? – pmg

+0

una stringa, supponiamo che qualcosa come questo imp = "test"; – Unzi

risposta

43

Questo avviso è il modo di gcc di dirti che non è possibile verificare l'argomento della stringa di formato per la funzione di stile printf (printf, fprintf ... ecc.). Questo avvertimento viene generato quando il compilatore non può controllare manualmente la stringa e assicurarsi che tutto vada come si desidera durante il runtime. Vediamo un paio di esempi.

Caso 1. Questa stringa può essere verificata al momento della compilazione e il compilatore lo permetterà senza preavviso:

printf("This string has no format"); 

Caso 2: Per questo caso, il compilatore in grado di rilevare che si dispone di un specificatore di formato e genererà un avviso diverso. Sulla mia macchina diceva "avviso: troppo pochi argomenti per il formato".

// This will most probably crash your machine 
printf("Not a safe string to %s"); 

Caso 3. Ora, questo è un po 'il tuo caso. Stai prendendo una stringa generata in fase di esecuzione e provando a stamparla. L'avvertenza che stai ricevendo è il compilatore che ti avverte che potrebbe esserci uno specificatore di formato nella stringa. Supponiamo per es. "% Sdata scaduto". In questo caso, il runtime proverà ad accedere a un argomento inesistente per corrispondere a% s. Ancora peggio, questo potrebbe essere un utente che cerca di sfruttare il tuo programma (facendolo leggere dati che non sono sicuri da leggere).

char str[200]; 
scanf("%s", str) 
printf(str) 
+0

Chiamare una funzione che si aspetta un 'const char *' e dargli un 'char *' non causerebbe un avvertimento, IMHO – terminus

+0

Non stavo suggerendo che la stringa fosse cast per const. Stavo citando che il secondo argomento deve essere specificato per correggere l'avviso. –

+0

Cosa intendi con "specificare un argomento"? – UncleBens

14

Anche se tecnicamente non c'è niente di male a chiamare una funzione printf-like con una stringa, è ancora cattiva pratica perché la stringa può contenere token di formato come %s. Ad esempio, se imp è %s test, accadranno cose brutte.

Se si desidera stampare lo imp senza formattazione, è necessario utilizzare fputs(imp, fil) (notare gli argomenti invertiti).

+8

Ancora peggio: se l'utente può specificare la stringa imp, potrebbe essere in grado di utilizzare il token di formato% n per sovrascrivere la memoria. Questo è noto come attacco di tipo format string e può essere usato per eseguire codice iniettato. – ollb

+3

fputs fa il trucco per scrivere una stringa sans% formattazione. –

+0

Cosa intendi con "formattazione sans%"? – TheRookierLearner

Problemi correlati