Ostrzeżenie: formatowanie nie jest ciągiem znaków i nie ma argumentów formatowania

Chcę usunąć ostrzeżenie, które dostaję w tej linii kodu,

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

Rzecz w tym, że kiedy to robię, zapisuje na pliku dokładnie to, co chcę, ale jeśli zastosuję format %s, to nie, jak to

fprintf(fil, "%s", imp);
Author: James McNellis, 2010-12-12

2 answers

To Ostrzeżenie jest sposobem gcc na poinformowanie Cię, że nie może zweryfikować argumentu formatu string do funkcji stylu printf (printf, fprintf... itp.). To Ostrzeżenie jest generowane, gdy kompilator nie może ręcznie zajrzeć do ciągu znaków i upewnić się, że wszystko pójdzie tak, jak chcesz podczas wykonywania. Spójrzmy na kilka przykładów.

Przypadek 1. Ten ciąg może być zweryfikowany podczas kompilacji i kompilator pozwoli na to bez ostrzeżenia:

printf("This string has no format");

Przypadek 2: w tym przypadku, kompilator może wykryć, że masz określony format i wyświetli inne Ostrzeżenie. Na mojej maszynie było napisane "Uwaga: za mało argumentów dla formatu".

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

Przypadek 3. To w pewnym sensie twoja sprawa. Pobierasz ciąg znaków wygenerowany w czasie wykonywania i próbujesz go wydrukować. Ostrzeżenie, które otrzymujesz, to kompilator ostrzegający Cię, że w ciągu znaków może być określony format. Powiedzmy na przykład "bad % sdata". W takim przypadku runtime spróbuje uzyskać dostęp do nieistniejącego argumentu co gorsza, może to być użytkownik próbujący wykorzystać twój program (powodując, że odczytuje dane, które nie są bezpieczne do odczytania).

char str[200];
scanf("%s", str)
printf(str)
 50
Author: Sanjit Saluja,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-10 15:09:26

Chociaż technicznie nie ma nic złego w wywołaniu funkcji podobnej do printf z łańcuchem znaków, nadal jest to zła praktyka, ponieważ łańcuch może zawierać tokeny formatu, takie jak %s. Jeśli imp jest %s test na przykład, złe rzeczy się wydarzą.

Jeśli chcesz wydrukować imp bez formatowania, powinieneś użyć fputs(imp, fil) (zwróć uwagę na odwrócone argumenty).

 16
Author: terminus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-11 02:36:58