2012-07-20 18 views

Odpowiedz

18

Identyfikatory w globalnej przestrzeni nazw zaczynające się od _ są zarezerwowane dla implementacji. _snprintf to tylko funkcja dostarczona przez implementację (Visual Studio). Jeśli chodzi o to uzasadnienie, Visual Studio implementuje C89, a snprintf jest częścią późniejszego standardu C99.

Poza tym, semantyka obu funkcji są różne w typie powrotnej, która w snprintf zawsze jest liczba znaków, że sformatowany ciąg trwa (czy nie było w buforze wystarczająco dużo miejsca, czy nie, natomiast _snprintf powróci a. liczba ujemna jeśli nie ma w buforze wystarczająco dużo miejsca

Oznacza to, że aby przydzielić bufor wystarczająco duży dla wyjścia można zrobić:

int size = snprintf(0, 0, "%s %d\n", str, i); 
char * buffer = malloc(size+1); 
snprintf(buffer, size+1, "%s %d\n", str, i); 

nie można tego zrobić z _snprintf jako na ly informacją, że funkcja zwraca się z powrotem, jest to, że obecny rozmiar nie jest wystarczający.

11

snprintf() nie był jeszcze częścią standardu w czasie, w którym środowisko wykonawcze C firmy Microsoft zaczęło go obsługiwać.

Ponieważ prototyp funkcji nie był ustandaryzowany, a programiści nie chcieli używać nazwy snprintf (w przypadku, gdy standard określał później inny prototyp), zdecydowali się dodać wiodący znak podkreślenia oznaczający funkcję jako Microsoft rozszerzenie do standardu.

3

Dodając do powyższego

istnieje właściwa C99 snprintf() i vsnprintf() dostępny od Visual Studio 2015

i nawet nie wywołać znanego niebezpieczny ostrzeżenie funkcja amortyzacji.
_snprintf_s() lub _vsnprintf_s(), o ile zostały dostarczone, są "bezpiecznymi wariantami" funkcji specyficznych dla MSVC, z zachowaniem innym niż C99.

0

Oprócz innej wartości zwracanej w przypadku niewystarczająco dużego bufora (opisanego w odpowiedzi Davida), funkcje z grupy _sn... różnią się od standardu snprintf pod innym ważnym względem. Jeśli bufor docelowy jest za krótki tylko jednym znakiem, funkcje _sn... uważają tę sytuację za "sukces".

Mówiąc bardziej szczegółowo, jeśli bufor cel jest na tyle długi, aby przechowywać całej sekwencji otrzymanej ale bez zakończenia zerowym postaci funkcje _sn... nie skrócić wynik nie zapisu kończące zera do bufora docelowego i w rezultacie zwróć rozmiar bufora. Tak więc, w ogólnym przypadku wynik nie ma zagwarantowanego zerowania.

W tej samej sytuacji snprintf odrzuci ostatni znak wynikowej sekwencji i na jego miejsce wypisze terminator zerowy. Wynik snprintf jest zawsze zakończony zerem.

Powiązane problemy