2012-03-31 9 views
8

Sie können Strings gestutzt mit einem printf Feld Breitenbezeichner:Maximale Druckfeldbreite für Zahlen angeben (ggf. abschneiden)?

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

> abcde 

Leider hat es nicht für Zahlen arbeiten (als Ersatz für d mit x gleich ist):

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

> 1234 

Gibt es eine einfache/trivialer Weg, um die Anzahl der zu druckenden Ziffern anzugeben, auch wenn es bedeutet, eine Zahl abzuschneiden?

MSDN speziell says that it will not happen, die unnötig begrenzend scheint. (Ja, es kann getan werden, indem Strings und so, aber ich hoffe auf eine “printf trick” oder clevere Kludge.)

Antwort

15

Wie viele meiner besten Ideen kam die Antwort zu mir im Bett liegend, warten auf den Herbst schlafend (zu dieser Zeit gibt es nicht viel anderes zu tun als zu denken).

Modul verwenden!

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 

Es ist nicht ideal, weil es nicht von links gestutzt kann (zum Beispiel 12 statt 34), aber es funktioniert für die wichtigsten Anwendungsfälle. Zum Beispiel:

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

Wenn Sie von links abschneiden wollen, sind die Werte unter der Annahme, sind integer, nur teilen. zB: '1234/100 // für 12' –

+0

@ortang, ja, ich weiß, aber es ist [nicht das gleiche wie von rechts abgeschnitten] (http://stackoverflow.com/questions/9953125/9957649?noredirect= 1 # Kommentar34294951_22533677). – Synetech

3

Wenn Sie von rechts nach gestutzt möchten Sie Ihre Zahl in einen String umwandeln kann und dann die Zeichenfolge Feld Breitenbezeichner verwenden.

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

Ich habe bereits bestätigt, dass Sie sie in Strings konvertieren; Diese Frage bezieht sich auf rohe Zahlen. Vermutlich (jemand müsste das überprüfen, um sicher zu sein, aber es scheint vernünftig), ist die Konvertierung in 'printf' optimaler als eine manuelle Konvertierung. – Synetech

0

Sie snprintf nutzen könnten von rechts von links

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

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

Das verwendet einen Puffer und fest codierte Werte, so dass es noch weniger ideal ist - die Verwendung von dynamisch zugewiesenem Speicher wäre noch schlimmer. – Synetech

0

Warum nicht abschneiden? der einzige Unterschied ist, einfache Division zu verwenden:

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

Als ich sagte, dass meine Lösung nicht von links abgeschnitten werden kann, habe ich nicht gemeint, dass es nicht möglich ist; Wie Sie gezeigt haben, können Sie Division verwenden. Der Grund, warum ich es nicht benutzt habe, ist, dass man im Gegensatz zum Modul, das leicht die rechten * n * Ziffern einer * beliebigen * Zahl geben kann, um die Anzahl der Ziffern in der Zahl vorher zu verringern Sie können teilen (in Ihrem Beispiel müssen Sie 1000 anstelle von 100 verwenden, wenn die Zahl 12345 war). Dies schafft viel mehr Arbeit, um zuerst die Anzahl der Ziffern zu bestimmen, dann multipliziere 10, um eine Maske zu erhalten, dann dividiere alles, um es nur zu kürzen. ': - /' – Synetech

+0

Es kann (wahrscheinlich) Kantenfälle geben, an die ich nicht denke, aber etwas wie 'num/pow (10, (int) log10 (num) - Ziffern + 1);' sollte für einfach funktionieren Fälle (angenommen Basis 10). –

0

Beispiel von Bash-Befehlszeile:

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