2010-12-11 98 views
37

Je veux enlever l'avertissement que je reçois sur cette ligne du code,Avertissement: format non une chaîne littérale et aucun argument de format

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

la chose est quand je fais cela, il écrit sur le fichier exactement ce que je veux, mais si je demande le format% s il n'a pas, comme celui-ci

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

Qu'est-ce que 'imp' contient? – casablanca

+1

Que se passe-t-il si vous remplacez fprintf par 'fputs (imp, fil);'? – pmg

+0

une chaîne, supposons quelque chose comme ça imp = "test"; – Unzi

Répondre

43

Cet avertissement indique à gcc qu'il ne peut pas vérifier l'argument chaîne de format de la fonction de style printf (printf, fprintf ... etc). Cet avertissement est généré lorsque le compilateur ne peut pas jeter un coup d'œil dans la chaîne et s'assurer que tout ira comme prévu pendant l'exécution. Regardons quelques exemples.

Cas 1. Cette chaîne peut être vérifiée au moment de la compilation et le compilateur lui permettra sans avertissement:

printf("This string has no format"); 

Cas n ° 2: Dans ce cas, le compilateur peut détecter que vous avez spécificateur de format et soulèvera un avertissement différent. Sur ma machine il a dit "avertissement: trop peu d'arguments pour le format".

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

Cas 3. Maintenant, c'est un peu votre cas. Vous prenez une chaîne générée lors de l'exécution et essayez de l'imprimer. L'avertissement que vous obtenez est le compilateur vous avertissant qu'il pourrait y avoir un spécificateur de format dans la chaîne. Dites par exemple "mauvais% sdata". Dans ce cas, le runtime essayera d'accéder à un argument inexistant pour correspondre au% s. Pire encore, il peut s'agir d'un utilisateur qui tente d'exploiter votre programme (l'amenant à lire des données qui ne sont pas sûres à lire).

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

Appeler une fonction qui attend un 'const char *' et lui donner un 'char *' ne provoquerait pas d'avertissement, à mon humble avis – terminus

+0

Je ne suggérais pas que la chaîne soit convertie en const. Je mentionnais que le deuxième argument doit être spécifié pour corriger l'avertissement. –

+0

Qu'entendez-vous par "spécifier un argument"? – UncleBens

14

Bien que techniquement il n'y a rien de mal à appeler une fonction semblable à printf avec une chaîne, il est encore une mauvaise pratique, car la chaîne peut contenir des jetons de format comme %s. Si imp est %s test par exemple, de mauvaises choses vont se produire.

Si vous souhaitez simplement imprimer le imp sans le formater, vous devez utiliser fputs(imp, fil) (notez les arguments inversés).

+8

Pire encore: si l'utilisateur peut spécifier la chaîne d'imp, il peut être capable d'utiliser le jeton de format% n pour écraser la mémoire. Ceci est connu sous le nom d'attaque de chaîne de format et peut être utilisé pour exécuter du code injecté. – ollb

+3

fputs fait l'affaire pour écrire une chaîne sans% mise en forme. –

+0

Que voulez-vous dire par "sans% formatting"? – TheRookierLearner