看前须知
题目内容
问题描述
在C语言中,标准库函数printf可进行格式输出。编写程序,实现一种类似printf中的字符串格式输出,其从控制台读入一个格式控制串和一行待输出的字符串,然后按照该格式控制串中的格式要求将该行字符串输出到控制台。格式控制串的格式要求如下:
%[-]m:nS
格式控制串除了末尾有换行符外没有其他空白符;第一个字符是“%”;中括号表示其内字符可省略,字符“-”若省略,表示输出字符串靠左对齐,否则表示靠右对齐;m和n是大于0小于100的整数,两整数之间以字符“:”分隔;m表示只输出字符串中的前m个字符,若m大于字符串的长度,则表示字符串全部输出;n表示输出的字符串至少占n个字符宽度,若n大于待输出的字符串长度,则多余的位置以字符“#”填充,若n小于等于待输出的字符串长度,则按照实际字符串输出,无需填充。
输入形式
从控制台读入格式控制串和待输出的字符串,第一行为格式控制串,第二行为待输出的字符串(字符串长度不超过100),第二行末尾的换行符不属于待输出的字符串。
输出形式
按照上述格式控制要求,将输入的第二行字符串输出到控制台。
样例
【样例1输入】
%-20:30S
Hello, word!
【样例1输出】
##################Hello, word!
【样例2输入】
%8:30S
Hello, word!
【样例2输出】
Hello, w######################
样例说明
【样例1说明】
根据第一行的格式控制要求,要将第二行的前20个字符按照右对齐输出,最少占30个字符的宽度。因为待输出的字符串只有12个字符(注意:字符w前有个空格),所以要全部输出,并且在左边填充18个“#”字符。
【样例2说明】
根据第一行的格式控制要求,要将第二行的前8个字符按照左对齐输出,最少占30个字符的宽度。待输出的字符串有12个字符,只输出前8个字符,并且在右边填充22个“#”字符。
题解
易错点和难点
本题很简单,只要分类讨论即可
首先先分类讨论是左对齐还是右对齐(判断字符串的第二个位置是否为 ‘-’ ),然后用strchr定位到冒号的位置,之后分别求出m,n。之后在利用字符串长度和m的最小值得到需要输出长度,然后在分类讨论输出时是否需要加 # ,思路很简单,操作也不难
参考代码
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
#include<stdbool.h>
char op[2000];
char s[2000];
char tmp[2000];
int flag=0,m,n,i,j=0,l,finlen;
char *p=NULL;
int min(int x, int y){ //找出较小的数
return x <= y ? x : y;
}
int main()
{
scanf("%s",op);//读取格式控制串
getchar();
gets(s); //读取待输出的字符串
l=strlen(s);
if(op[1]=='-')
{
flag=1; //第一次分类讨论判断对齐方向
}
if(flag==1)
{
j=0;
p=strchr(op,':'); //找到 :的位置
for(i=2;i<p-op;i++)
{
tmp[j]=op[i];
j++;
}
m=atoi(tmp); //得到m
//printf("%d\n",m);
j=0;
memset(tmp,0,sizeof(tmp));
for(i=p-op+1;i<strlen(op)-1;i++)
{
tmp[j]=op[i];
j++;
}
n=atoi(tmp); //得到n
//printf("%d\n",n);
finlen=min(m,l); //得到输出长度
if(n-finlen<=0) //第二次分类讨论判断是否需要补充 #
{
for(i=0;i<finlen;i++)
{
putchar(s[i]);
}
}
else
{
for(i=0;i<n-finlen;i++) //补充
{
printf("#");
}
for(i=0;i<finlen;i++)
{
putchar(s[i]);
}
}
}
else
{
j=0;
p=strchr(op,':');//找到 :的位置
for(i=1;i<p-op;i++)
{
tmp[j]=op[i];
j++;
}
m=atoi(tmp); //得到m
//printf("%d\n",m);
j=0;
memset(tmp,0,sizeof(tmp));
for(i=p-op+1;i<strlen(op)-1;i++)
{
tmp[j]=op[i];
j++;
}
n=atoi(tmp); //得到n
//printf("%d\n",n);
finlen=min(m,l); //得到输出长度
if(n-finlen<=0) //第二次分类讨论判断是否需要补充 #
{
for(i=0;i<finlen;i++)
{
putchar(s[i]);
}
}
else
{
for(i=0;i<finlen;i++)
{
putchar(s[i]);
}
for(i=0;i<n-finlen;i++)
{
printf("#");
}
}
}
return 0;
}
补充测试的数据
测试点5
输入
%2:2S
Hello, word!
(空格Hello, word!)
输出
H
(空格H)