C语言K&R习题1-20、1-21(改),用空格模拟tab;用tab代替连续空格。

 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值