1-20 用空格模拟tab
这个比较简单啊,利用变量len记录当前字符位置,用TABEND-TABEND%len得到空格数量,打印即可。
# include<stdio.h>
// detab,用空格替代制表位
# define TABEND 8
// 设置制表位列数为8
int main()
{
int len=0,c;
while((c=getchar())!=EOF)
{
if(c!='\t' && c!='\n')
{
putchar(c);
++len;
}
else if(c == '\n')
{
putchar(c);
len = 0;
}
else if(c=='\t')
{
for(int i=TABEND - len % TABEND;i>0;--i)
{
printf(" ");
len=0;
}
}
}
}
1-21 用最少的tabs和blanks模拟连续的空格。
这个代码debug了好久,感觉比1-20难太多,详见注释。
思路固化了,应该有很多简单的方法。
# include<stdio.h>
// entab,用制表位代替空格
# define TABEND 8
// 设置制表位列数为8
int main()
{
int c,lastc=0,blanks=1,tabs=0; // c用于存输入字符;lastc存上一个输入字符;blanks存连续空格的数目;tabs存制表符数目;
int bls=0,pos=0; // bls存需要补充的空格;pos存当前单词的位置,计算与下一个制表符的距离。
while((c=getchar())!=EOF)
{
if(c!=' ' && c!='\n')
{
if(c=='\t') // 由于制表符应使pos为0,此处while末尾有pos+1,故此处令pos为-1。
{
pos = -1;
}
if(lastc == ' ') // 若当前c为非空格,lastc为空格,证明出现了连续空格,且连续空格已经结束,空格数目为blanks。
{
if(blanks<=(TABEND-pos)) // TABEND-pos为与下一个制表符的距离,blanks小于此值说明无法用tab替代空格,只能原样输出。
{
while(blanks>0)
{
printf(" ");
pos++;
if (pos==TABEND) // 此处实际可以删除,在每个pos变动时均判断方便理解,若pos==TABEND,pos归零。
{
pos=0;
}
blanks--;
}
}
else // 若blanks大于TABEND-pos,此距离可用一个制表符填补,还剩blanks-(TABEND-pos)个空格需处理。
{
bls=(blanks-TABEND+pos) % TABEND; //能用tab的用tab填补,符合题目要求。(用最少的tabs和blanks填补连续blanks)
tabs=(blanks-TABEND+pos) / TABEND;
while(tabs+1) // tabs+1中的“1”用于填补TABEND-pos。
{
printf("\t"); // 用制表符填补后记得把pos归0。
pos=0;
tabs--;
}
while(bls)
{
printf(" ");
pos++;
if (pos==TABEND)
{
pos=0;
}
bls--;
}
}
blanks=1; // blanks替换完成后将其复位。blanks初始值为1。reason:从第二个加到最后一个,遗漏了第一个blank。
}
putchar(c);
pos++;
if (pos==TABEND)
{
pos=0;
}
lastc = c;
}
else if(c == '\n') // 回车后代表第一行已经输入完成,pos归零。
{
putchar(c);
pos=0;
lastc = c;
}
else if(c==' ') // 从连续blanks的第二个blank开始记录。
{
if (lastc == ' ')
{
blanks++;
}
else
lastc = c;
}
}
return 0;
}