2010-09-22 10 views
78

Załóżmy, że masz napis, który NIE jest null zakończony i znasz dokładny rozmiar, więc jak możesz wydrukować ten ciąg z printf w C? Pamiętam taką metodę, ale nie mogę dowiedzieć się, teraz ...Używanie printf z nie kończącym się łańcuchem znaków

+6

'W kontekście C', wszystkie ciągi są zerowa zakończone. Tablice znaków bez wartości zerowej nie są ciągami znaków ... są tablicami znaków char :) – pmg

+3

możliwy duplikat [Jak mogę wydrukować łańcuch zakończony znakiem null za pomocą printf?] (Http://stackoverflow.com/ pytania/2137779/how-do-i-print-a-non-null-ended-string-using-printf) – Justin

+0

https://stackoverflow.com/questions/2239519/is-there-a-way-to-specify -how-many-characters-of-a-string-to-print-out-using-pri –

Odpowiedz

129

Istnieje możliwość z printf, to idzie tak:

printf("%.*s", stringLength, pointerToString); 

Nie ma potrzeby, aby skopiować wszystko, nie ma potrzeby modyfikowania oryginał ciąg lub bufor.

+9

Ale w każdym razie jest to niebezpieczne, ktoś pewnego dnia wydrukuje ten ciąg z% s – pmod

+0

Tak, to jest to! – whoi

+4

@Pmod: Niekoniecznie, jeśli bufor nie jest wystawiony na działanie zewnętrznego świata. Jest również bardzo przydatne, aby wydrukować * części * ciągu znaków (oczywiście może to być wartość pusta). Jeśli naprawdę chcesz zobaczyć to w akcji, spójrz na serwer proxy OpenSER/Kamailio SIP, gdzie unika się kopiowania ze względu na tę technikę (również za pomocą sprintf). – DarkDust

1
#include<string.h> 
int main() 
{ 
/*suppose a string str which is not null terminated and n is its length*/ 
int i; 
for(i=0;i<n;i++) 
{ 
printf("%c",str[i]); 
} 
return 0; 
} 

edytowany kod, herezje inny sposób:

#include<stdio.h> 
int main() 
{ 
printf ("%.5s","fahaduddin");/*if 5 is the number of bytes to be printed and fahaduddin is the string.*/ 

return 0; 

} 
+0

Bardzo zła wydajność ze względu na mnóstwo niepotrzebnych odczytów bajtów (które są objęte karą za wydajność jeśli bajt nie znajduje się na adresie wyrównanym do słów na większości procesorów), a także formatowanie i stosowanie jest wykonywane dla każdego znaku. Nie rób tego :-) Zobacz moją odpowiedź na rozwiązanie. – DarkDust

+0

Dzięki za wzmiankę o –

+0

@DarkDust: tylko maszyna patologiczna będzie karać bajtów czyta nie wyrównane do granic słów. Czy myślisz o tym, że odczyty słów nie są wyrównane do granic słów? A może jakieś staromodne bzdury czy coś takiego? –

5

printf("%.*s", length, string) nie zadziała.

Oznacza to, że należy wydrukować UP TO length bytes LUB bajt zerowy, zależnie od tego, co nastąpi wcześniej. Jeśli Twoja tablica-znaków z zakończonymi znakami NU zawiera bajty o wartości NUŻEJ, to printf zatrzyma się na nich i nie będzie kontynuował.

+13

Jak może pojawić się wartość zerowa w niezerowej macierzy zakończonej tablicą znaków? Pomyśl o tym ... – pmg

+2

to zadziała dla niego, ponieważ zna dokładną długość – BlackBear

+4

A jak to jest odpowiedź na pytanie PO? – Shahbaz

12

Możesz użyć fwrite() na standardowe wyjście!

fwrite(your_string, sizeof(char), number_of_chars, stdout); 

ten sposób wyświetli pierwszych znaków (liczba określona w number_of_chars zmiennych) do pliku, w tym przypadku na stdout (standardowe wyjście, ekran)!

+0

Bardzo pomocne, gdy chcesz sprawdzić długi bufor zawierający ciągi i zera! – Elist

19

Oto wyjaśnienie, jak działa %.*s i gdzie jest określony.

Specyfikacje konwersji w ciąg szablonu printf mają ogólną postać:

% [ param-no $] flags width [ . precision ] type conversion 

lub

% [ param-no $] flags width . * [ param-no $] type conversion 

Druga forma jest dla uzyskania dokładności z listy argumentów:

Możesz także określić dokładność "*". Oznacza to, że następny argument na liście argumentów (przed faktyczną wartością do wydrukowania) jest używany jako dokładność. Wartość musi być int i jest ignorowana, jeśli jest ujemna.

- Output conversion syntax w instrukcji glibc

Dla %s formatowania strun, precyzja ma szczególne znaczenie:

Precyzyjny można określić, aby wskazać maksymalną liczbę znaków do zapisu; w przeciwnym razie znaki w łańcuchu do kończącego znaku pustego, ale bez niego, zostaną zapisane w strumieniu wyjściowym.

- w podręczniku glibc

Inne użyteczne warianty:

  • "%*.*s", maxlen, maxlen, val będzie prawym uzasadnić, wstawianie spacji przed;
  • "%-*.*s", maxlen, maxlen, val Zostanie wyjustowany.
+0

Jeśli dobrze rozumiem, następujące elementy padłyby na wyjście, ale nadal zapobiegają przepełnieniu łańcucha? '"% - *. * S ", dopełnienie, str_view.size(), str_view.data()' – scx

1
printf("%.5s", pointerToNonNullTerminatedString); 

Długość ciąg będzie 5.

Powiązane problemy