Jak sformatować łańcuchy za pomocą printf (), aby uzyskać równą długość w wyniku?

97

Mam dwie funkcje, jedną, która generuje komunikaty, Starting initialization...a drugą, która sprawdza kody powrotu i wyjścia "Ok", "Warning"lub "Error". Jednak generowany plik wyjściowy ma inną długość:

Starting initialization...Ok.
Checking init scripts...Ok.

Jak mogę dostać coś takiego:

Starting initialization...       Ok.
Checking init scripts...         Ok.
psihodelia
źródło

Odpowiedzi:

164

Możesz określić szerokość pól tekstowych, np

printf("%-20s", "initialization...");

a następnie cokolwiek zostanie wydrukowane w tym polu, zostanie wypełnione pustymi wartościami do wskazanej szerokości.

-Lewej uzasadnia swój tekst w tej dziedzinie.

Carl Smotricz
źródło
130
Niestety, nie jestem na tyle sprytny, by liczyć tak wysoko. Jednak ufam, że pytający będzie wystarczająco inteligentny, aby ekstrapolować z mojego przykładu :)
Carl Smotricz
3
co z prawem uzasadnionym? Nie ma żadnych flag wymienionych w K&R
Ungeheuer
9
Wyrównanie do prawej jest ustawieniem domyślnym. Bez znaku -Twoje dane będą wyjustowane w polu, którego szerokość określiłeś.
Carl Smotricz
25

printfumożliwia formatowanie za pomocą specyfikatorów szerokości. na przykład


printf( "%-30s %s\n", "Starting initialization...", "Ok." );

Możesz użyć ujemnego specyfikatora szerokości, aby wskazać wyrównanie do lewej, ponieważ domyślnie jest używane wyrównanie do prawej.

PP.
źródło
20

Dodatkowo, jeśli chcesz mieć elastyczność wyboru width, możesz wybrać jeden z dwóch następujących formatów (z obcinaniem lub bez):

int width = 30;
//no truncation uses %-*s
printf( "%-*s %s\n", width, "Starting initialization...", "Ok." );
// output is "Starting initialization...     Ok."

//truncated to the specified width uses %-.*s
printf( "%-.*s %s\n", width, "Starting initialization...", "Ok." ); 
// output is "Starting initialization... Ok."
równowaga życiowa
źródło
13

Jest też %nmodyfikator, który może pomóc w pewnych okolicznościach. Zwraca kolumnę, w której ciąg był do tej pory. Przykład: chcesz napisać kilka wierszy, które znajdują się w szerokości pierwszego wiersza, tak jak tabela.

int width1, width2;
int values[6][2];
printf("|%s%n|%s%n|\n", header1, &width1, header2, &width2);

for(i=0; i<6; i++)
   printf("|%*d|%*d|\n", width1, values[i][0], width2, values[i][1]);

wypisze 2 kolumny o tej samej szerokości, niezależnie od długości dwóch ciągów header1i header2może mieć. Nie wiem, czy wszystkie implementacje mają to, %nale Solaris i Linux mają.

Patrick Schlüter
źródło
To rozwiązanie działa, ale każdy, kto to bierze i umieszcza w swoim kodzie, powinien być świadomy ryzyka wprowadzenia luk w pamięci .
Matthew Cole,
0

Istnieje również mało zaawansowane technologicznie rozwiązanie polegające na liczeniu dodawania spacji ręcznie, aby Twoje wiadomości były wyrównane. Nic nie stoi na przeszkodzie, aby w ciągu wiadomości umieścić kilka spacji na końcu.

Carl Smotricz
źródło
-2

Zacznij od użycia tabulatorów, modyfikatora znaku \ t . Przejdzie do stałej lokalizacji (kolumny, żargon terminala). Jednak to nie pomaga, jeśli są różnice większe niż szerokość kolumny (4 znaki, o ile dobrze pamiętam).

Aby to naprawić, napisz swoje "OK / NOK" używając ustalonej liczby zakładek (5? 6 ?, spróbuj), a następnie zwróć ( \ r ) bez nowej linii i napisz wiadomość.

jpinto3912
źródło
5
Zawsze istnieje niebezpieczeństwo, że ciąg jest dłuższy niż tabulator, co zmusi wynikowy tabulator i tekst do niewłaściwego wyrównania.
PP.
Niezupełnie ... najpierw napisz z zakładkami OK / NOK, potem / r, teraz napisz frazę, teraz / n. Fraza może nadpisać OK / NOK. Ale twoja droga jest o wiele lepsza, nie wiedziałem o negatywnym usprawiedliwieniu.
jpinto3912