2012-03-31 78 views
8

可以截断与printf场宽度指定字符串:为数字指定最大的printf字段宽度(如果需要,截断)?

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

> abcde 

遗憾的是它不换号工作(更换dx是一样的):

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

> 1234 

有一个简单的/即使它意味着截断一个数字,指定要打印的数字的数量也很简单吗?

MSDN特别是says that it will not happen似乎不必要的限制。 (是的,它可以通过创建字符串等,但我希望“printf trick”或聪明kludge。)

回答

15

像我的许多最好的想法,答案来到我躺在床上,等待下降睡着了(当时没有什么比想象的更好的了)。

使用模量!

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 

这不是理想的,因为它不能从左侧(例如,12代替34)截断,但它工作的主要用例。例如:

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

如果你想从左边截断,假设值是整数,只是划分。例如:'1234/100 // for 12' – 2014-03-20 12:34:33

+0

@ortang,是的,我知道,但它[与右截断不一样](http://stackoverflow.com/questions/9953125/9957649?noredirect= 1个#comment34294951_22533677)。 – Synetech 2014-03-20 14:25:35

3

如果要从右侧截断,可以将数字转换为字符串,然后使用字符串字段宽度说明符。

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

我已经承认你将它们转换为字符串;这个问题是关于原始数字。据推测(有人必须检查确定,但看起来合理),“printf”中的转换比手动转换更为优化。 – Synetech 2013-05-12 13:54:35

0

你可以使用的snprintf从右侧

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

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

它使用缓冲区和硬编码值,所以它更不理想 - 使用动态分配的内存会更糟糕。 – Synetech 2014-02-10 20:30:33

0

为什么不从左边截断?唯一的区别是使用简单的除法:从bash命令行

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

当我说我的解决方案不能从左侧截断时,我并不是说这是不可能的;正如你演示的那样,你可以使用除法。我之所以不使用它的原因是因为不同于可以很容易地给出* any *号的最右* n *数字的模数,要从左边截断,您必须首先确定数字中的数字位数你可以划分(在你的例子中,如果数字是12345,你必须使用'1000'而不是'100')。这将首先确定数字的位数,然后乘以10得到一个蒙版,然后进行分割,所有这些只是为了截断。 ': - /' – Synetech 2014-03-20 14:24:41

+0

可能有(可能是)边缘情况我没有想到,但像'num/pow(10,(int)log10(num) - digits + 1);'应该为简单案例(假设基数为10)。 – 2016-06-02 20:21:30

0

例子:

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