2012-03-31 6 views
8

È possibile troncare stringhe con un printf campo a larghezza specificatore:Specificare la larghezza massima del campo printf per i numeri (troncando se necessario)?

printf("%.5s", "abcdefgh"); 

> abcde 

Purtroppo non funziona per i numeri (sostituendo d con x è lo stesso):

printf("%2d", 1234); // for 34 
printf("%.2d", 1234); // for 34 
printf("%-2d", 1234); // for 12 
printf("%-.2d", 1234); // for 12 

> 1234 

c'è un facile/modo banale per specificare il numero di cifre da stampare anche se significa troncare un numero?

MSDN in particolare says that it will not happen che sembra limitare inutilmente. (Sì, può essere fatto creando stringhe e cose simili, ma spero in un o in un astuto kludge.)

risposta

15

Come molte delle mie migliori idee, la risposta è venuta da me mentre ero a letto, aspettando di cadere addormentato (non c'è molto altro da fare in quel momento che pensare).

Modulo di utilizzo!

printf("%2d\n", 1234%10); // for 4 
printf("%2d\n", 1234%100); // for 34 

printf("%2x\n", 1234%16); // for 2 
printf("%2x\n", 1234%256); // for d2 

Non è l'ideale, perché non può troncare da sinistra (per esempio, invece di 1234), ma funziona per i principali casi d'uso. Per esempio:

// print a decimal ruler 
for (int i=0; i<36; i++) 
    printf("%d", i%10); 
+1

Se si desidera troncare sulla sinistra, assumendo i valori sono interi, basta dividere. es .: '1234/100 // per 12' –

+0

@ortang, sì, lo so, ma è [non è come troncare da destra] (http://stackoverflow.com/questions/9953125/9957649?noredirect= 1 # comment34294951_22533677). – Synetech

3

Se si desidera troncare da destra è possibile convertire il numero in una stringa e quindi utilizzare il campo di stringa di larghezza identificatore.

"%.3s".format(1234567.toString) 
+1

Ho già riconosciuto di convertirli in stringhe; questa domanda riguarda i numeri grezzi. Presumibilmente (qualcuno dovrebbe controllare per essere sicuro, ma sembra ragionevole), la conversione in 'printf' è più ottimale di una conversione manuale. – Synetech

0

Si potrebbe utilizzare snprintf per troncare da destra

char buf[10]; 
static const int WIDTH_INCL_NULL = 3; 

snprintf(buf, WIDTH_INCL_NULL, "%d", 1234); // buf will contain 12 
+0

Questo utilizza un buffer e valori hardcoded, quindi è ancora meno ideale l'utilizzo della memoria allocata dinamicamente sarebbe anche peggio. – Synetech

0

Perché non da sinistra? l'unica differenza è usare semplice divisione:

printf("%2d", 1234/100); // you get 12 
+2

Quando ho detto che la mia soluzione non può troncare da sinistra, non intendevo che non fosse possibile; come hai dimostrato, puoi usare la divisione. Il motivo per cui non l'ho usato è perché a differenza del modulo che può facilmente darti le cifre * n * più a destra di * qualsiasi * numero, per troncare da sinistra, devi prima determinare il numero di cifre nel numero prima puoi dividere (nel tuo esempio, devi usare '1000' invece di' 100' se il numero fosse '12345'). Questo crea molto più lavoro per determinare prima il numero di cifre, quindi moltiplicare 10 per ottenere una maschera, quindi dividere, tutto solo per troncare. ': - /' – Synetech

+0

Ci possono essere (probabilmente sono) casi limite che non sto pensando, ma qualcosa come 'num/pow (10, (int) log10 (num) - cifre + 1);' dovrebbe funzionare per semplice casi (assumendo la base 10). –

0

Esempio da linea di comando Bash:

localhost ~$ printf "%.3s\n" $(printf "%03d" 1234) 
123 
localhost ~$