Jestem na tyle niefortunny, że utknąłem przy użyciu VS 2010 dla projektu i zauważyłem, że następujący kod nadal nie jest kompilowany przy użyciu niezgodnego ze standardami kompilatora:
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
char buffer[512];
snprintf(buffer, sizeof(buffer), "SomeString");
return 0;
}
(kompilacja kończy się niepowodzeniem i pojawia się błąd: C3861: „snprintf”: nie znaleziono identyfikatora)
Pamiętam, że tak było w przypadku VS 2005 i jestem zszokowany, widząc, że nadal nie został naprawiony.
Czy ktoś wie, czy Microsoft planuje przenieść swoje standardowe biblioteki C na rok 2010?
c
visual-studio-2010
Andrzej
źródło
źródło
Odpowiedzi:
Krótka historia: Microsoft w końcu zaimplementował snprintf w Visual Studio 2015. We wcześniejszych wersjach można go zasymulować jak poniżej.
Długa wersja:
Oto oczekiwane zachowanie snprintf:
Wersje wcześniejsze niż Visual Studio 2015 nie miały implementacji zgodnej. Istnieją zamiast tego niestandardowe rozszerzenia, takie jak
_snprintf()
(które nie zapisują terminatora null przy przepełnieniu) i_snprintf_s()
(które mogą wymusić zakończenie zerowe, ale zwraca -1 przy przepełnieniu zamiast liczby znaków, które zostałyby zapisane).Sugerowane rozwiązanie zastępcze dla VS 2005 i nowszych:
źródło
snprintf
nie jest częścią C89. Jest standardem tylko w C99. Microsoft nie ma planu obsługującego C99 .(Ale jest to również standard w C ++ 0x ...!)
Zobacz inne odpowiedzi poniżej, aby obejść ten problem.
źródło
_snprintf
jest niebezpieczną funkcją, która zachowuje się inaczej niżsnprintf
(niekoniecznie dodaje terminator zerowy), więc porada podana w tej odpowiedzi jest myląca i niebezpieczna.Jeśli nie potrzebujesz zwracanej wartości, możesz również zdefiniować snprintf jako _snprintf_s
źródło
Uważam, że odpowiednikiem systemu Windows jest
sprintf_s
źródło
sprintf_s
zachowuje się inaczej niżsnprintf
.Kolejny bezpieczny zamiennik
snprintf()
ivsnprintf()
jest zapewniany przez ffmpeg. Możesz sprawdzić źródło tutaj (sugerowane).źródło
Wypróbowałem kod @Valentin Milea, ale otrzymałem błędy związane z naruszeniem dostępu. Jedyną rzeczą, która działała dla mnie, była implementacja Insane Coding: http://asprintf.insanecoding.org/
W szczególności pracowałem ze starszym kodem VC ++ 2008. Od realizacji kodowania za Insane (można pobrać z linku powyżej), użyłem trzy pliki:
asprintf.c
,asprintf.h
ivasprintf-msvc.c
. Inne pliki były przeznaczone dla innych wersji MSVC.[EDYTUJ] Aby uzyskać kompletność, ich zawartość jest następująca:
asprintf.h:
asprintf.c:
vasprintf-msvc.c:
Użycie (część
test.c
dostarczona przez Insane Coding):źródło