Niejednoznaczność zaczyna się od samego standardu C. Zarówno C99, jak i C11 mają identyczny opis snprintffunkcji. Oto opis z C99:
7.19.6.5 snprintfFunkcja
Streszczenie
1 #include <stdio.h>
int snprintf(char * restrict s, size_t n, const char * restrict format, ...);
Opis
2 snprintfFunkcja jest równoważna fprintf, z tym wyjątkiem, że dane wyjściowe są zapisywane w tablicy (określonej przez argument s), a nie w strumieniu. Jeśli nwynosi zero, nic nie jest zapisywane i smoże być pustym wskaźnikiem. W przeciwnym razie znaki wyjściowe poza n-1st są odrzucane, a nie zapisywane w tablicy, a znak null jest zapisywany na końcu znaków faktycznie zapisanych w tablicy. Jeśli kopiowanie odbywa się między nakładającymi się obiektami, zachowanie jest niezdefiniowane.
Zwraca
3 snprintfFunkcja zwraca liczbę znaków, które zostałyby zapisanenbyły wystarczająco duże, nie licząc kończącego znaku null lub wartości ujemnej, jeśli wystąpił błąd kodowania. W związku z tym dane wyjściowe zakończone znakiem null zostały całkowicie zapisane wtedy i tylko wtedy, gdy zwrócona wartość jest nieujemna i mniejsza niż n.
Z jednej strony zdanie
W przeciwnym razie znaki wyjściowe poza n-1st są odrzucane, a nie zapisywane w tablicy, a znak null jest zapisywany na końcu znaków faktycznie zapisanych w tablicy
mówi, że
jeśli ( swskazuje na tablicę składającą się z 3 znaków i) nwynosi 3, to zostaną zapisane 2 znaki, a znaki poza drugim są odrzucane ; wtedy znak null jest zapisywany po tych 2 (a znak null będzie trzecim zapisanym znakiem) .
I to, jak sądzę, odpowiada na pierwotne pytanie.
ODPOWIEDŹ:
Jeśli kopiowanie odbywa się między nakładającymi się obiektami, zachowanie jest niezdefiniowane.
Jeśli nwynosi 0, nic nie jest zapisywane na wyjściu, w
przeciwnym razie, jeśli nie napotkano błędów kodowania, wyjście jest ZAWSZE zakończone znakiem null ( niezależnie od tego, czy dane wyjściowe mieszczą się w tablicy wyjściowej, czy nie ; jeśli nie, to niektóre znaki są odrzucane, tak że wynik tablica nigdy nie jest przepełniona), w
przeciwnym razie (jeśli wystąpią błędy kodowania) dane wyjściowe mogą pozostać niezerowe .
Z drugiej strony
Ostatnie zdanie
Zatem wyjście zakończone znakiem null zostało całkowicie zapisane wtedy i tylko wtedy, gdy zwrócona wartość jest nieujemna i mniejsza niż n
daje niejednoznaczność (lub mój angielski nie jest wystarczająco dobry). Mogę zinterpretować to zdanie na co najmniej dwa sposoby:
1. Wyjście jest zakończone wartością zerową wtedy i tylko wtedy, gdy zwrócona wartość jest nieujemna i mniejsza niżn (co oznacza, że jeśli zwrócona wartość jest nie mniejsza niż n, tj. Dane wyjściowe (w tym kończący znak null) nie mieści się w tablicy, wtedy dane wyjściowe nie są zakończone znakiem null ).
2. Dane wyjściowe są kompletne (żadne znaki nie zostały odrzucone) wtedy i tylko wtedy, gdy zwrócona wartość jest nieujemna i mniejsza niżn .
Uważam, że powyższa interpretacja 1 jest sprzeczna z ODPOWIEDZI, powoduje nieporozumienia i długie dyskusje. Dlatego ostatnie zdanie opisujące snprintffunkcję wymaga zmiany w celu usunięcia wszelkich niejasności (co daje podstawy do napisania Propozycji na Standard języka C).
Uważam, że przykład niejednoznacznego sformułowania można znaleźć na stronie http://en.cppreference.com/w/c/io/fprintf (zobacz 4)), dzięki @ "Martin Ba" za link.
Zobacz także pytanie „ snprintf: Czy są jakieś propozycje / plany C Standardu zmiany opisu tej funkcji? ”.