Pytanie:
Dlaczego parametr „n” snprintf jest ignorowany?
Westin
2018-10-21 01:00:04 UTC
view on stackexchange narkive permalink

Zauważyłem, że parametr n funkcji snprintf () wydaje się być ignorowany w moim kodzie.

  char asdf [10 ]; Serial1.println (snprintf (asdf, 2, "hello"));  

Wypisuje 5, gdy spodziewałbym się wydrukowania 2. Co się dzieje?

Czy zmienna „asdf” zawiera „hello” lub „h”? Jeśli zawiera „h”, to parametr nie został zignorowany.
Trzy odpowiedzi:
JRobert
2018-10-21 01:15:52 UTC
view on stackexchange narkive permalink

snprintf () nie zapisze więcej znaków niż <size> (2d argument snprintf) do twojego bufora, ale zlicza (i odrzuca dodatkowe) znaki, które by napisał, gdyby było wystarczająco dużo miejsca i to jest liczba, którą zwroty. Tak, to może być mylące!

Zobacz tę dokumentację dotyczącą snprintf ().

Byłoby to pomocne, ponieważ można by `snprintf` do bardzo małego bufora, zanotować zwracaną liczbę, a następnie` malloc` do bufora o odpowiednim rozmiarze i zrobić to ponownie. W ten sposób wiesz, ile bajtów chcesz przydzielić.
@NickGammon: Lub możesz `snprintf` do żadnego bufora (pusty wskaźnik docelowy jest wyraźnie opisany jako prawidłowy argument dla przypadku destlength == 0) podczas pomiaru długości.
W rzeczy samej. Odbywa się to również w procedurach wyjścia tekstu systemu Windows, aby zmierzyć, ile miejsca zajmowałby jakiś tekst w jakiejś czcionce, bez faktycznego rysowania go.
Jot
2018-10-21 01:23:48 UTC
view on stackexchange narkive permalink

Szkic testowy dla Arduino Uno:

  char buffer [10]; void setup () {Serial.begin (9600); int n = snprintf (bufor, 2, "witaj"); Serial.println (n); Serial.println (buffer);} void loop () {}  

Jak napisał @JRobert, kluczem jest „would have”. O ile wiem, tylko snprintf i vsnprintf zwracają liczbę „would have”.

Myślę, że powodem jest to, że mogę powiedzieć jeśli ciąg został obcięty. Załóżmy, że parametr „size” ma wartość 25, a ciąg formatu jest bardzo długi, wówczas wartość zwracaną można porównać z 25. Jeśli wartość zwracana wynosiła 26 (liczba bajtów „miałaby”), to ciąg został obcięty. Tej informacji nie można było pobrać, gdy numer „by miał” nie był dostępny.

Greenonline
2018-10-21 01:41:07 UTC
view on stackexchange narkive permalink

Na koniec, strona podręcznika dla fprintf stwierdza:

Funkcja snprintf () powinna być równoważna sprintf (), z dodatkiem argumentu n określającego rozmiar bufora, do którego odwołuje się s. Jeśli n wynosi zero, nic nie zostanie zapisane, a s może być pustym wskaźnikiem. W przeciwnym razie bajty wyjściowe poza n-pierwszym powinny zostać odrzucone zamiast zapisywane w tablicy, a bajt zerowy jest zapisywany na końcu bajtów faktycznie zapisanych w tablicy.

i , bardziej istotne:

Po pomyślnym zakończeniu funkcja snprintf () zwróci liczbę bajtów, które zostałyby zapisane w s, gdyby n było wystarczająco duże, z wyłączeniem kończącego bajtu zerowego.



To pytanie i odpowiedź zostało automatycznie przetłumaczone z języka angielskiego.Oryginalna treść jest dostępna na stackexchange, za co dziękujemy za licencję cc by-sa 4.0, w ramach której jest rozpowszechniana.
Loading...