/**Write a program that converts upper case to lower or lower case to upper, depending
* on the name it is invoked with as found in argv[0]**/#include<stdio.h>#include<ctype.h>#include<string.h>voidprintc(int(*f)(int)){char c;while((c=getchar())!=EOF)putchar(f(c));}intmain(int argc,char* argv[]){if(strcmp(argv[0],"lower")==0)printc(tolower);if(strcmp(argv[0],"upper")==0)printc(toupper);return0;}
P2
/**
* write a program that will print arbitrary input in a sensible way. As a minimum, it
* should print non graphic characters in octal or hexadecimal according to local custom,
* and break long text lines.
**/#include<stdio.h>#define LINELEN 14#define OCTLEN 3intprintnor(int c,int n){int len;if((len=(n+1))<=LINELEN)printf("%c",c);elseprintf("\n%c",c);return len;}intprintoct(int c,int n){int len;if((len=(n+OCTLEN))<=LINELEN)printf("%o",c);elseprintf("\n%o",c);return len;}intmain(){int c,cnum =0;while((c=getchar())!=EOF){
cnum=(c<32)?printoct(c,cnum):printnor(c,cnum);if(cnum>=LINELEN)
cnum=cnum-LINELEN;}return0;}
P3
/**
* Revise miniprintf to handle more of the other
* facilities of printf
**/#include<stdio.h>#include<stdarg.h>voidminiprintf(char* fmt,...){
va_list ap;char*p,*sval;int ival;double dval;va_start(ap, fmt);// make ap point ot 1st unnamed argfor(p = fmt;*p; p++){if(*p !='%'){putchar(*p);continue;}switch(*++p){case'i':case'd':
ival =va_arg(ap,int);printf("%d", ival);break;case'o':
ival =va_arg(ap,int);printf("%o", ival);break;case'X':case'x':
ival =va_arg(ap,int);printf("%x", ival);break;case'u':
ival =va_arg(ap,int);printf("%u", ival);break;case'c':
ival =va_arg(ap,int);printf("%c", ival);break;case'G':case'g':case'E':case'e':case'f':
dval =va_arg(ap,double);printf("%f", dval);break;case's':for(sval =va_arg(ap,char*);*sval; sval++)putchar(*sval);break;default:putchar(*p);break;}}va_end(ap);// clean up when done}intmain(){miniprintf("This is Spart%c!\n",'a');}
P4
/**
* Write a private version of scanf analogous to
* miniprintf from the previous section
**/#include<stdio.h>#include<stdarg.h>voidkeep_reading(){char c;while((c=getchar())!='\n'||c!=EOF);}intmscanf(char* fmt,...){
va_list ap;char*p,*sval,c;int ival,count=0;double dval;va_start(ap, fmt);// make ap point ot 1st unnamed argfor(p = fmt;*p; p++){if(*p !='%'){
c =getchar();if(c !=*p){keep_reading();return0;}elsecontinue;}switch(*++p){case'd':
ival =va_arg(ap,int);
count +=scanf("%d",&ival);break;case'f':
dval =va_arg(ap,double);
count +=scanf("%lf",&dval);break;case's':
sval =va_arg(ap,char*);
count +=scanf("%s", sval);break;default:printf("wrong format!");return0;}}va_end(ap);// clean up when donereturn count;}intmain(){int a;scanf("-%d",&a);//-114514printf("%d\n",a);//114514}
P5
/**
* Rewrite the postfix calculator of Chapter 4 to
* use scanf and/or sscanf to do the input and
* number conversion
**/#include<stdio.h>#include<ctype.h>#define MAXLINE 114doubleatof(char s[]){double val,power;int i,sign;for(i=0;s[i]==' ';i++);
sign =(s[i]=='-')?-1:1;if((s[i]=='+')||(s[i]=='-'))
i++;for(val=0.0;isdigit(s[i]);i++)
val=val*10.0+(s[i]-'0');if(s[i]=='.')
i++;for(power=1.0;isdigit(s[i]);i++){
val=10.0*val+(s[i]-'0');
power*=10.0;}return(sign*val/power);}intmain(){double sum,atof(char s[]);char s[MAXLINE];int x;
sum =0;while(scanf("%s",s)!=EOF)printf("\t%g\n",sum+=atof(s));return0;}
P6
/**
* Write a program to compare two files, printing the first
* line where thet differ.
**/#include<stdio.h>#include<string.h>#define MAXLINE 114intmain(int argc,char* argv[]){
FILE *f1,*f2;char l1[MAXLINE], l2[MAXLINE];char*prog = argv[0];if(argc !=3){printf("error: the program takes 2 arguments;\n");return0;}elseif((f1 =fopen(*++argv,"r"))!=NULL)if((f2 =fopen(*++argv,"r"))!=NULL)while(fgets(l1, MAXLINE, f1)!=NULL&&fgets(l2, MAXLINE, f2)!=NULL){if(strcmp(l1, l2)!=0){printf("%s", l1);printf("%s", l2);fclose(f1);fclose(f2);return0;}}else{fprintf(stderr,"%s can't open %s", prog,*argv);exit(1);}else{fprintf(stderr,"%s can't open %s", prog,*argv);exit(1);}printf("Identical lines\n");return0;}
P7
/** Modify the pattern finding program of Chapter 5 to take its input from a
* set of named files or, if no files are named as arguments, form the standard
* input. Should the file name be printed when a matching line is found?
**/#include<stdio.h>#include<string.h>#define MAXLINE 1919#define PATTERNLEN 114intgetline(char* s,int lim){int c,i;
i=0;while(--lim>0&&(c==getchar())!=EOF&&c!='\n')
s[i++]=c;if(c=='\n')
s[i++]=c;
s[i]='\0';return i;}intmain(int argc,char* argv[]){
FILE *f;char line[MAXLINE],*pattern;long lineno =0;int c, except =0, number =0, found =0;int argn =1;while(++argn < argc &&((*++argv)[0]=='-'))while(c =*++argv[0])switch(c){case'x':
except =1;break;case'n':
number =1;break;default:printf("find: illegal option %c\n", c);
argc =0;
found =-1;break;}if(argn++<= argc){
pattern =*argv;if(argn <= argc){
lineno =0;while(*++argv !=NULL){printf("%s\n",*argv);if((f =fopen(*argv,"r"))!=NULL){while(fgets(line, MAXLINE, f)!=NULL){
lineno++;if((strstr(line, pattern)!=NULL)!= except){if(number)printf("%ld:", lineno);printf("%s", line);
found++;}}}elseprintf("error: could not open %s",*argv);}}elsewhile(getline(line, MAXLINE)>0){
lineno++;if((strstr(line, pattern)!=NULL)!= except){if(number)printf("%ld:", lineno);printf("%s", line);
found++;}}}elseprintf("Usage: find -x -n pattern [textfile\\s]\n");return found;}
P8
/**
* Write a program to print a set of files, starting each
* new one on a new page, with a title and a running page
* count for each file.
**/#include<stdio.h>#define MAXLINE 1919#define PAGEROWS 81intcount_pages(FILE* f){int rows=0;char line[MAXLINE];while((fgets(line,MAXLINE,f))!=NULL)
rows++;rewind(f);return rows/PAGEROWS+1;}intmain(int argc,char* argv[]){
FILE* f;int pages =0,rows,i;char line[MAXLINE];intcount_pages(FILE *f);if(argc==1){printf("Not enough parameters!\n");return0;}elsewhile(--argc >0)if((f =fopen(*++argv,"r"))!=NULL){
pages =count_pages(f);printf("File: %s, %d pages\n",*argv, pages);
rows =0;if((fgets(line, MAXLINE, f))==NULL)printf("NULL");while((fgets(line, MAXLINE, f))!=NULL){
rows++;printf("%s", line);}for(i = rows % PAGEROWS; i <= PAGEROWS; i++)printf("\n");fclose(f);}else{fprintf(stderr,"can't open file %s",*argv);exit(1);}return0;}
P9
/**
* functions like isupper can be implemented to save space
* or to save time. Explore both possibilities.
**///二种形式#include<stdio.h>#include<ctype.h>#include<string.h>intisupper(int c){return(c>='A'&&c<='Z');}intisupper(int c){return(strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ",c)!=NULL);}
《The C Programming Language》答案(第七章)我的新站P1/**Write a program that converts upper case to lower or lower case to upper, depending * on the name it is invoked with as found in argv[0]**/#include <...