练习5-11 修改程序entab和detab,使他们接受一组作为参数的制表符停止位。如果启动程序时不带参数,则使用默认的制表符停止位设置

来源:互联网 发布:cf手游m249天羽数据 编辑:程序博客网 时间:2024/06/05 05:33

1.1、制表符停止位间隔一样的entab简单程序

#include <stdio.h>#include <stdlib.h>#define TABINC 8main(int argc,char *argv[]){    int c,nb,nt,pos,tabincrement;    nb=nt=0;    if(argc<2)        tabincrement=TABINC;    else        //tabincrement=atoi(*++argv);        tabincrement=atoi(argv[1]);    for(pos=1;(c=getchar())!=EOF;++pos){        if(c==' '){            if(pos%tabincrement!=0){                ++nb;            }            else{                nb=0;                ++nt;            }        }        else{            for( ;nt>0;--nt){                putchar('\t');            }            if(c=='\t'){                nb=0;            }            else{                for( ;nb>0;--nb){                    putchar(' ');                }            }            putchar(c);            if(c=='\n')                pos=0;            else if(c=='\t')                pos=pos+(tabincrement-(pos-1)%tabincrement)-1;        }    }}

输入输出(b、c间隔着5个空格):

exam5-11-1 6ab     cdefab       cdef

不对齐了,测试了下答案也没对齐。制表符停止位每隔6位一个。题意是要像word里制表位一样,设置几个制表符停止位(没设置的仍按默认)。


1.2、错误程序:

#include <stdio.h>#include <stdlib.h>#define MAXLINE 100#define TABINC 8void entab(int ntab,char *tab);main(int argc,char *argv[]){    entab(argc-1,*++argv);}void entab(int ntab,char *tab){    int c,nb,nt,pos,flag;    char *r;    r=tab;    nb=nt=0;    flag=(ntab<1)? 0:1;    for(pos=1;(c=getchar())!=EOF;++pos){        if(c==' '){            if(flag && pos<MAXLINE ? pos<atoi(tab) : pos%TABINC!=0){                ++nb;                printf("tab:%d-nb:%d\n",atoi(tab),nb);            }            else{                nb=0;                ++nt;                ++tab;            }        }        else{            for( ;nt>0;--nt){                putchar('\t');            }            if(c=='\t'){                nb=0;            }            else{                for( ;nb>0;--nb){                    putchar(' ');                }            }            putchar(c);            if(c=='\n'){                pos=0;                tab=r;            }            else if(c=='\t')                if(flag)                    pos=(pos<MAXLINE) ? atoi(tab) : pos+(TABINC-(pos-1)%TABINC)-1;                else                    pos=pos+(TABINC-(pos-1)%TABINC)-1;        }    }}

输入exam5-11-my 6 15(ab、cf间6个空格):

ab      cfabaaaaaacf //示意

输出(cf前相当于17个空格):

abtab:6-nb:1tab:6-nb:2tab:6-nb:3tab:115-nb:1                 cfaaaaaaaaaaaaaaaaacf //示意

错误调试(后面调试发现115与15相关,输入25则输出225):

void entab(int ntab,char *tab){    printf("%s \n",tab);    printf("%s ",++tab);/* 不能加? */}

entab改成如上,命令行输入exam5-11-my 6 15,第二个printf无输出。

用于比较的测试1(较exam5-3和exam5-10):

#include <stdio.h>void abc(char *ss);main(){    char s[6];    s[0]='a';    s[1]='p';    s[2]='p';    s[3]='l';    s[4]='e';    s[5]='\0';    printf("%s\n",s);    /*    for(i=0;i<5;++i)        *s++=getchar();    */    abc(s);    printf("%s",s);}void abc(char *ss){    int i;    for(i=0;i<5;++i)        *ss++=getchar();    *ss='\0';}

输入abcdef,输出abcde:

appleabcdefabcde

指针到底什么时候能加,什么时候不能加?

测试2

#include <stdio.h>void printabc(char *nname);main(){    char *name[]={        "January","February"    };    printabc(*name);}void printabc(char *nname){    printf("%s\n",nname);    printf("%s",++nname);}

输出(nname=*name是指向January首字母指针,++nname并非预想的指向February,而是指向第二个字母):

Januaryanuary

前面错误调试并非无输出,命令行输入exam5-11-my 34
输出:

argc=2argv[0]=exam5-11-myargv[1]=34344

1.3、正确程序,与答案思路不同,直接把制表符停止位传给entab函数,需注意++指针的指向:

#include <stdio.h>#include <stdlib.h>#define MAXLINE 100#define TABINC 8void entab(int ntab,char **tab);main(int argc,char * argv[]){    entab(argc-1,argv);}void entab(int ntab,char **tab){    int c,nb,nt,pos,flag;    char **s,*r;    /* tab=argv; */    s=tab;    r=*++tab;    nb=nt=0;    flag=(ntab<1)? 0:1;    for(pos=1;(c=getchar())!=EOF;++pos){        if(c==' '){            if(flag && pos<MAXLINE && r<=*(s+ntab) ? pos<atoi(r) : pos%TABINC!=0){                ++nb;            }            else{                nb=0;                ++nt;                if(flag && r<*(s+ntab))                    r=*++tab;            }        }        else{            for( ;nt>0;--nt){                putchar('\t');            }            if(c=='\t'){                nb=0;            }            else{                for( ;nb>0;--nb){                    putchar(' ');                }            }            putchar(c);            if(c=='\n'){                pos=0;                r=*(s+1);            }            else if(c=='\t')                if(flag)                    pos=(pos<MAXLINE&& r<=*(s+ntab)) ? atoi(r) :                     pos+(TABINC-(pos-1)%TABINC)-1;                else                    pos=pos+(TABINC-(pos-1)%TABINC)-1;        }    }}

条件表达式可能还需要根据实际entab实现目标略作修改,以上程序在最大制表符停止位和MAXLINE内,采用参数制表符停止位,在其外采用默认的。答案程序当pos>MAXLINE时,空格都当成制表符,也不恰当。答案settab和tabpos示意:

[NO][NO][NO][NO][YES][NO][NO][NO][YES][NO] YES YES YES YES                停止位           停止位     超出MAXLINE

2.1、detab程序

#include <stdio.h>#include <stdlib.h>#define TABINC 8void detab(int ntab,char **tab);main(int argc,char * argv[]){    detab(argc-1,argv);}void detab(int ntab,char **tab){    int c,pos,nb,flag;    char **s,*r;    pos=1;    s=tab;    r=*++tab;    flag=(ntab<1)? 0:1;    while((c=getchar())!=EOF){        if(c=='\t'){            while(flag && atoi(r)-pos<0)                r=*++tab;            nb=(flag && r<=*(s+ntab))? atoi(r)-pos+1 :             TABINC-(pos-1)%TABINC;            while(nb>0){                putchar(' ');                ++pos;                --nb;            }        }        else if(c=='\n'){            putchar(c);            pos=1;            r=*(s+1);        }        else{            putchar(c);            ++pos;        }    }}

while(flag && atoi(r)-pos<0)中flag不能少,否则没有制表符停止位参数时,atoi(r)出错。

0 0
原创粉丝点击