2010-09-22 11 views
78

Supponi di avere una stringa che NON sia null terminata e che tu conosca la sua dimensione esatta, quindi come puoi stampare quella stringa con printf in C? Ricordo un tale metodo, ma non riesco a trovare fuori ora ...Utilizzo di printf con una stringa terminata non nulla

+6

Nel contesto 'C', tutte le stringhe sono nulli terminati. Le matrici di caratteri senza nullo in esse non sono stringhe ... sono matrici di caratteri :) – pmg

+3

possibili duplicati di [Come stampare una stringa non terminata da null usando printf?] (Http://stackoverflow.com/ domande/2137779/how-do-i-print-a-non-null-terminated-string-using-printf) – Justin

+0

https://stackoverflow.com/questions/2239519/is-there-a-way-to-specify -come-molti-caratteri-di-una-stringa-per-stampare-usare-pri- –

risposta

129

C'è una possibilità con printf, va in questo modo:

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

Non c'è bisogno di copiare nulla, non c'è bisogno di modificare l'originale stringa o buffer.

+9

Ma comunque è pericoloso, qualcuno un giorno stamperà questa stringa con% s – pmod

+0

Sì, è così! – whoi

+4

@Pmod: non necessariamente se il buffer non è esposto al mondo esterno. È anche molto utile stampare semplicemente * parti * di una stringa (che può essere terminata con null, ovviamente). Se vuoi davvero vederlo in azione, dai un'occhiata al proxy SIP OpenSER/Kamailio dove evitano di copiare molto cose grazie a questa tecnica (anche usando 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; 
} 

Ho modificato il codice, ecco un altro modo:

#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

Prestazioni pessime a causa di molte letture di byte non necessarie (che vengono con una penalizzazione delle prestazioni se il byte non è su un indirizzo allineato alla parola sulla maggior parte delle CPU) e anche l'analisi e l'analisi della formattazione viene eseguita per ciascun carattere. Non farlo :-) Vedi la mia risposta per la soluzione. – DarkDust

+0

Grazie per aver menzionato –

+0

@DarkDust: solo una macchina patologica penalizza le letture dei byte non allineate ai limiti delle parole. Stai pensando a letture di parole non allineate ai confini delle parole? O qualche antica merda di mips o qualcosa del genere? –

5

printf("%.*s", length, string) non funzionerà.

Ciò significa stampare fino a byte di lunghezza O un byte nullo, a seconda di cosa si verifica per primo. Se il tuo array-of-char non terminato da null contiene byte null PRIMA della lunghezza, printf si fermerà su quelli e non continuerà.

+13

come può apparire un null in un array-of-char terminato non-null? Pensaci ... – pmg

+2

funzionerà per lui perché conosce la lunghezza esatta – BlackBear

+4

E come è questa la risposta alla domanda dell'OP? – Shahbaz

12

È possibile utilizzare un fwrite() allo stdout!

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

In questo modo si emette i primi caratteri (numero definito in number_of_chars variabile) in un file, in questo caso per stdout (lo standard output, il vostro schermo)!

+0

Molto utile quando si desidera ispezionare un buffer lungo contenente stringhe e zeri! – Elist

19

Ecco una spiegazione di come funziona %.*s e dove è specificato.

Le specifiche di conversione in una stringa di modello printf hanno la forma generale:

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

o

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

La seconda forma è per ottenere la precisione dalla lista degli argomenti:

È inoltre possibile specificare una precisione di '*'. Ciò significa che l'argomento successivo nell'elenco degli argomenti (prima del valore effettivo da stampare) viene utilizzato come precisione. Il valore deve essere un int e viene ignorato se è negativo.

- Output conversion syntax nel manuale glibc

Per %s formattazione di stringhe, di precisione ha un significato speciale:

Una precisione può essere specificato per indicare il numero massimo di caratteri per scrivere; in caso contrario, i caratteri nella stringa fino a non includere il carattere null terminante vengono scritti nel flusso di output.

- nel manuale glibc

Altre varianti utili:

  • "%*.*s", maxlen, maxlen, val saranno destro giustificare, l'inserimento di spazi prima;
  • "%-*.*s", maxlen, maxlen, val verrà giustificato a sinistra.
+0

Se ho capito bene, quanto segue potrebbe riempire l'output e impedire comunque un overflow di stringa? '"% - *. * S ", padding, str_view.size(), str_view.data()' – scx

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

La lunghezza stringa sarà 5.

Problemi correlati