Warning: "format not a string literal and no format arguments"

Od aktualizacji do najnowszej wersji Xcode 3.2.1 i Snow Leoparda otrzymuję Ostrzeżenie [6]}

"format nie jest literalny i nie ma argumentów formatu"

Z następującego kodu:

NSError *error = nil;

if (![self.managedObjectContext save:&error]) 
{
    NSLog([NSString stringWithFormat:@"%@ %@, %@", 
       errorMsgFormat, 
       error, 
       [error userInfo]]);      

}

Jeśli errorMsgFormat jest NSString ze specyfikatorami formatu (np: "print me like this: %@"), co jest nie tak z powyższym wywołaniem NSLog? A jaki jest zalecany sposób, aby to naprawić, aby ostrzeżenie nie zostało wygenerowane?

Author: jscs, 2009-11-05

11 answers

Czy prawidłowo zagnieżdżasz nawiasy? Nie wydaje mi się, że lubisz brać tylko jeden argument, czyli to, co przekazujesz. Ponadto już formatuje za Ciebie. Dlaczego po prostu tego nie zrobisz?

NSLog(@"%@ %@, %@", 
   errorMsgFormat, 
   error, 
   [error userInfo]);              

Lub, skoro mówisz errorMsgFormat jest ciągiem formatującym z jednym symbolem zastępczym, próbujesz to zrobić?

NSLog(@"%@, %@", [NSString stringWithFormat:errorMsgFormat, error], 
   [error userInfo]);              
 113
Author: Sixten Otto,
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
2009-11-05 01:54:13

Xcode narzeka, ponieważ jest to problem z bezpieczeństwem.

Oto kod podobny do twojego:

NSString *nameFormat = @"%@ %@";
NSString *firstName = @"Jon";
NSString *lastName = @"Hess %@";
NSString *name = [NSString stringWithFormat:nameFormat, firstName, lastName];
NSLog(name);

To ostatnie polecenie NSLog będzie wykonywało odpowiednik tego:

NSLog(@"Jon Hess %@");

To spowoduje, że NSLog będzie szukał jeszcze jednego argumentu string, ale go nie ma. Ze względu na sposób, w jaki działa język C, odbierze on losowy wskaźnik śmieci ze stosu i spróbuje traktować go jak NSString. Najprawdopodobniej spowoduje to awarię programu. Teraz twój struny prawdopodobnie nie mają w sobie %@' s, ale pewnego dnia mogą. Jako pierwszy argument funkcji przyjmujących ciągi formatujące (printf, scanf, NSLog, -[NSString stringWithFormat:], należy zawsze używać ciągu formatującego z danymi, które bezpośrednio kontrolujesz ...).

Jak wskazuje Otto, powinieneś prawdopodobnie zrobić coś w stylu:

NSLog(errorMsgFormat, error, [error userInfo]);
 157
Author: Jon Hess,
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
2009-11-05 04:16:06

Ostatnia odpowiedź: jak powiedział Jon Hess, jest to problem bezpieczeństwa, ponieważ przekazujesz dowolny ciąg znaków do funkcji oczekującej ciągu formatu. Oznacza to, że oceni wszystkie SPECYFIKATORY FORMATU w ciągu whatever. Jeśli nie ma żadnych, super, ale jeśli są, złe rzeczy mogą się zdarzyć.

Właściwą rzeczą do zrobienia jest użycie bezpośrednio ciągu formatującego, na przykład

NSLog(@"%@", myNSString);

W ten sposób, nawet jeśli w myNSString są określone formaty, nie są one oceniane przez NSLog.

 38
Author: Alex Whittemore,
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
2010-08-18 00:01:43

Szczególnie nie polecam tego używać, ponieważ ostrzeżenie jest prawdziwym ostrzeżeniem.. w dynamicznym użyciu języka można wykonywać czynności runtime z łańcuchem znaków (tzn. wstawić nowe informacje lub nawet zawiesić program).. Jednak można wymusić stłumienie, jeśli wiesz, że powinno tak być i naprawdę nie chcesz być ostrzegany przed tym..

#pragma GCC diagnostic ignored "-Wformat-security"

Powie GCC, aby tymczasowo zignorowała ostrzeżenie o kompilacji.. Znowu nic nie rozwiązuje ale może być czasy, kiedy nie możesz znaleźć dobrego sposobu na naprawienie problemu.

EDIT: od clang, pragma się zmieniła. Zobacz to: https://stackoverflow.com/a/17322337/3937

 13
Author: Qrikko,
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
2017-05-23 11:46:38

Najszybszym sposobem na poprawienie tego byłoby dodanie @"%@", jako pierwszego argumentu do wywołania NSLog, tzn.

NSLog(@"%@", [NSString stringWithFormat: ....]);

Chociaż, prawdopodobnie powinieneś rozważyć szesnaście odpowiedzi Otto.

 10
Author: Anthony Cramp,
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
2009-11-05 04:01:13

Właśnie przekazałem zero, żeby zanegować ostrzeżenia, może to by Ci pomogło?

NSLog (myString, nil);

 10
Author: Martytoof,
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
2010-04-08 01:33:25

Jeśli chcesz pozbyć się ostrzeżenia" format not a string literal and no format arguments "raz na zawsze, możesz wyłączyć ustawienie Ostrzeżenia GCC "Typecheck Calls to printf / scanf" (GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO) w Ustawieniach budowania celu.

 3
Author: aldi,
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
2009-11-19 15:57:28

NSLog () oczekuje ciągu w formacie, to, co jest przekazywane, jest tylko ciągiem. Nie musisz używać stringWithFormat:, możesz po prostu zrobić:

NSLog(@"%@ %@, %@", errorMsgFormat, error, [error userInfo])

I to sprawi, że Ostrzeżenie zniknie.

 2
Author: Elfred,
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
2009-11-05 04:06:00

FWIW, dotyczy to również iPhone dev. Koduję na SDK 3.1.3 i mam ten sam błąd z tym samym problemem (zagnieżdżanie stringWithFormat wewnątrz NSLog ()). Sixten i Jon są na forsie.

 2
Author: Pettiross,
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
2010-05-19 17:47:00

Po prostu poinformowanie kogokolwiek za pomocą appendFormat na NSMutableString może również spowodować wyświetlenie tego ostrzeżenia, jeśli próbuje przekazać sformatowany łańcuch jak tak:

NSMutableString *csv = [NSMutableString stringWithString:@""];
NSString *csvAddition = [NSString stringWithFormat:@"%@",WHATEVERYOUAREPUTTINGINYOURSTRING];
[csv appendFormat:csvAddition];

Więc aby uniknąć tego ostrzeżenia, zamień powyższe w to:

NSMutableString *csv = [NSMutableString stringWithString:@""];
[csv appendFormat:@"%@",WHATEVERYOUAREPUTTINGINYOURSTRING];
Bardziej zwięzłe i bezpieczniejsze. Smacznego!
 0
Author: ColossalChris,
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
2015-09-10 21:15:49
NSLog(@"%@ %@, %@", 
       errorMsgFormat, 
       error, 
       [error userInfo]); 
 -2
Author: ILYA2606,
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
2014-04-22 13:34:09