Czy istnieje sposób określenia liczby znaków ciągu do wydrukowania przy użyciu funkcji printf ()?

127

Czy istnieje sposób określenia liczby znaków ciągu do wydrukowania (podobnie do miejsc dziesiętnych w ints)?

printf ("Here are the first 8 chars: %s\n", "A string that is more than 8 chars");

Chciałbym wydrukować: Here are the first 8 chars: A string

TTT
źródło

Odpowiedzi:

226

Podstawowy sposób to:

printf ("Here are the first 8 chars: %.8s\n", "A string that is more than 8 chars");

Drugi, często bardziej przydatny sposób to:

printf ("Here are the first %d chars: %.*s\n", 8, 8, "A string that is more than 8 chars");

Tutaj określasz długość jako argument int funkcji printf (), która traktuje „*” w formacie jako żądanie pobrania długości z argumentu.

Możesz również użyć notacji:

printf ("Here are the first 8 chars: %*.*s\n",
        8, 8, "A string that is more than 8 chars");

Jest to również analogiczne do notacji „% 8.8s”, ale ponownie umożliwia określenie minimalnej i maksymalnej długości w czasie wykonywania - bardziej realistycznie w scenariuszu takim jak:

printf("Data: %*.*s Other info: %d\n", minlen, maxlen, string, info);

Specyfikacja POSIX dla printf()definiuje te mechanizmy.

Jonathan Leffler
źródło
2
Do ostatniego przykładu: co się stanie, jeśli skopiowany ciąg jest krótszy niż minlen?
szukający prawdy
4
Dane wyjściowe będą puste (po lewej, chyba że dodasz a -), aby uzyskać pełną określoną długość.
Jonathan Leffler
13
printf ("Here are the first 8 chars: %.8s\n", "A string that is more than 8 chars");

% 8s określiłoby minimalną szerokość 8 znaków. Chcesz skrócić o 8, więc użyj% .8s.

Jeśli chcesz zawsze drukować dokładnie 8 znaków, możesz użyć% 8.8s

rozwojowa niemoc
źródło
13

Oprócz określenia stałej liczby znaków, możesz również użyć, *co oznacza, że ​​printf pobiera liczbę znaków z argumentu:

#include <stdio.h>

int main(int argc, char *argv[])
{
        const char hello[] = "Hello world";
        printf("message: '%.3s'\n", hello);
        printf("message: '%.*s'\n", 3, hello);
        printf("message: '%.*s'\n", 5, hello);
        return 0;
}

Wydruki:

message: 'Hel'
message: 'Hel'
message: 'Hello'
hlovdal
źródło
11

Używając printfmożesz zrobić

printf("Here are the first 8 chars: %.8s\n", "A string that is more than 8 chars");

Jeśli używasz C ++, możesz osiągnąć ten sam wynik, używając STL:

using namespace std; // for clarity
string s("A string that is more than 8 chars");
cout << "Here are the first 8 chars: ";
copy(s.begin(), s.begin() + 8, ostream_iterator<char>(cout));
cout << endl;

Lub mniej wydajnie:

cout << "Here are the first 8 chars: " <<
        string(s.begin(), s.begin() + 8) << endl;
Peter Alexander
źródło
1
Uwaga: nie używać ostream_iterator<char>(cout)! Zamiast tego użyj ostreambuf_iterator<char>(cout)! Różnica w wydajności powinna być dość duża.
Dietmar Kühl,
Sposób bardziej wydajny, aby zamiast używać: std::cout.write(s.data(), 8). Lub w nowoczesnych C ++ std::cout << std::string_view{s.data(), 8}.
Artyer
4

Wydrukuj pierwsze cztery znaki:

printf("%.4s\n", "A string that is more than 8 chars");

Zobacz ten link, aby uzyskać więcej informacji (sprawdź sekcję .precision)

Anssi
źródło
4

W C ++ jest to łatwe.

std::copy(someStr.c_str(), someStr.c_str()+n, std::ostream_iterator<char>(std::cout, ""));

EDYCJA: Bezpieczniej jest również używać tego z iteratorami ciągów, więc nie uciekniesz do końca. Nie jestem pewien, co się dzieje z printf i stringami, które są zbyt krótkie, ale myślę, że może to być bezpieczniejsze.

Chris H.
źródło
32
ha, tak, to jest „łatwe”. C ++ zawsze wygląda jak wypadek samochodowy.
Prezydent James K. Polk
nadal możesz zrobić printf () w c ++ :)
StasM
6
Myślę, że to był sarkazm. std::cout << someStr.substr(0,8);jest dużo bardziej oczywiste.
MSalters
2
@MSalters Powinieneś zamieścić to jako odpowiedź.
Jonathan Mee
1

W C ++ robię to w ten sposób:

char *buffer = "My house is nice";
string showMsgStr(buffer, buffer + 5);
std::cout << showMsgStr << std::endl;

Proszę zauważyć, że nie jest to bezpieczne, ponieważ przekazując drugi argument, mogę wyjść poza rozmiar ciągu i wygenerować naruszenie dostępu do pamięci. Aby tego uniknąć, musisz wdrożyć własną kontrolę.

rodolk
źródło