【蓝桥杯2015_C++】t4:格子中输出

这题考冷门知识点,提前科普:

下面这段来自C++ reference的printf(),*可作为一个设置输出宽度的占位符:

【蓝桥杯2015_C++】t4:格子中输出

翻译了一下:

(number) 要打印的最小字符数。如果要打印的值小于此数字,则结果将用空格填充。即使结果更大,也不会截断该值。

*               宽度不是在格式字符串中指定的,而是作为必须格式化的参数前面的附加整数值参数指定的。

可能还是看不懂,举个例子:

 printf ("Width trick: %*d ", 5, 10); 

输出结果:Width trick:    10

这里的*相当于一个设置宽度的数字的占位符,表示后面的这个%d要占多少个字符。我们可以数一下,10前面有4个空格。

下面我们来看代码:

 1 /*
 2 格子中输出
 3 StringInGrid函数会在一个指定大小的格子中打印指定的字符串。
 4 要求字符串在水平、垂直两个方向上都居中。
 5 如果字符串太长,就截断。
 6 如果不能恰好居中,可以稍稍偏左或者偏上一点。
 7 下面的程序实现这个逻辑,请填写划线部分缺少的代码。
 8 对于题目中数据,应该输出:
 9 +------------------+
10 | ? ? ? ? ? ? ? ? ?|
11 | ? ? abcd1234 ? ? |
12 | ? ? ? ? ? ? ? ? ?|
13 | ? ? ? ? ? ? ? ? ?|
14 +------------------+
15 */
16 #include <stdio.h>
17 #include <string.h>
18 void StringInGrid(int width, int height, const char* s)
19 {
20     int i,k;
21     char buf[1000];
22     strcpy(buf, s);
23     if(strlen(s)>width-2) buf[width-2]=0;
24     
25     printf("+");
26     for(i=0;i<width-2;i++) printf("-");
27     printf("+
");
28     
29     for(k=1; k<(height-1)/2;k++){
30         printf("|");
31         for(i=0;i<width-2;i++) printf(" ");
32         printf("|
");
33     }
34     
35     printf("|");
36     
37 //    printf("%*s%s%*s",--------------------------------------); //填空
38 
39     
40     printf("|
");
41     
42     for(k=(height-1)/2+1; k<height-1; k++){
43         printf("|");
44         for(i=0;i<width-2;i++) printf(" ");
45         printf("|
");
46     }    
47     
48     printf("+");
49     for(i=0;i<width-2;i++) printf("-");
50     printf("+
");    
51 }
52 
53 
54 int main()
55 {
56     StringInGrid(20,6,"abcd1234");
57     return 0;
58 }
View Code

可以先把要填空的地方注释掉运行一下:

【蓝桥杯2015_C++】t4:格子中输出

很明显,我们要填的就是居中打印字符串的代码。

经过上面对*的分析,我们大概已经能看懂这个 "%*s%s%*s" 的意思了,就是要打印的字符串前需要有多少空位,后面又需要有多少空位。

先试着填两个数字上去: printf("%*s%s%*s",10,"",buf,10,""); ,运行一下:

【蓝桥杯2015_C++】t4:格子中输出

数了下,前面10个空格,后面10个空格。大概能看明白了,因为要居中,其实左右边的空格数都是一样的,就是宽度-2-字符串长度(-2是有两个'|')

填空: printf("%*s%s%*s",(width-2-strlen(buf))/2,"",buf,(width-2-strlen(buf))/2,"");