Mam fragment kodu, w którym znajduje się plik
printf("%.*s\n")
co to %.*s
znaczy
Mam fragment kodu, w którym znajduje się plik
printf("%.*s\n")
co to %.*s
znaczy
Odpowiedzi:
Możesz użyć gwiazdki ( *
), aby przekazać specyfikator szerokości / precyzję do printf()
, zamiast zakodować go na stałe w ciągu formatu, tj.
void f(const char *str, int str_len)
{
printf("%.*s\n", str_len, str);
}
str_len
argument musi mieć typ int
(lub węższy typ całkowity, do którego zostałby podwyższony int
). Byłoby błędem, aby przejść long
, size_t
itp
%s
, jest wydrukowanie podłańcucha oryginalnego ciągu. W tym przypadku, str
wskazywałoby gdzieś wewnątrz oryginalnego łańcucha (prawdopodobnie na początku) i str_len
określił długość podłańcucha, który powinien zostać wydrukowany.
Więcej szczegółów tutaj .
wartość całkowita lub
*
określająca minimalną szerokość pola. Wynik jest uzupełniany znakami spacji (domyślnie), jeśli jest to wymagane, po lewej stronie, gdy jest wyrównany do prawej, lub po prawej, jeśli jest wyrównany do lewej. W przypadku użycia * szerokość jest określana przez dodatkowy argument typu int. Jeśli wartość argumentu jest ujemna, wynikiem jest określona flaga - i dodatnia szerokość pola. (Uwaga: jest to szerokość minimalna: wartość nigdy nie jest obcinana).
.
po którym następuje liczba całkowita lub *, lub żadna z tych wartości nie określa precyzji konwersji. W przypadku użycia * precyzja jest określana przez dodatkowy argument typu int. Jeśli wartość tego argumentu jest ujemna, jest ignorowana. Jeśli nie jest używana ani liczba, ani *, dokładność przyjmuje się jako zero. W poniższej tabeli przedstawiono dokładne efekty precyzji.
Więc jeśli spróbujemy obu specyfikacji konwersji
#include <stdio.h>
int main() {
int precision = 8;
int biggerPrecision = 16;
const char *greetings = "Hello world";
printf("|%.8s|\n", greetings);
printf("|%.*s|\n", precision , greetings);
printf("|%16s|\n", greetings);
printf("|%*s|\n", biggerPrecision , greetings);
return 0;
}
otrzymujemy wynik:
|Hello wo|
|Hello wo|
| Hello world|
| Hello world|
Nie sądzę, aby powyższy kod był poprawny, ale (zgodnie z tym opisem printf()
) .*
oznacza
Szerokość nie jest określona w ciągu formatu, ale jako dodatkowy argument wartości całkowitej poprzedzający argument, który ma zostać sformatowany. '
Jest to więc łańcuch o dopuszczalnej szerokości jako argument.
int
(lub jej podzbiorem) - a nie zwykłą wartością całkowitą, jak bardziej intuicyjna, size_t
lub jej możliwymi aliasami std::string::size_type
. Jest to jeszcze bardziej zagmatwane, biorąc pod uwagę, że strona, do której istnieje odwołanie, jest wymieniona size_t
jako jeden z obsługiwanych specyfikatorów typu.
Zobacz: http://www.cplusplus.com/reference/clibrary/cstdio/printf/
.*
Dokładność nie jest określona w ciągu formatu, ale jako dodatkowy argument wartości całkowitej poprzedzający argument, który ma zostać sformatowany.
s
Ciąg znaków
printf
połączenie.