《The C Programming Language》答案(第七章)

《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 <stdio.h>
#include <ctype.h>
#include <string.h>
void printc(int (*f)(int)){
    char c;
    while ((c=getchar())!=EOF)
        putchar(f(c));
}
int main(int argc,char* argv[]){
    if(strcmp(argv[0],"lower")==0)
        printc(tolower);
    if(strcmp(argv[0],"upper")==0)
        printc(toupper);
    return 0;
}

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 3
int printnor(int c,int n){
    int len;
    if((len=(n+1))<=LINELEN)
        printf("%c",c);
    else
        printf("\n%c",c);
    return len;
}
int printoct(int c,int n){
    int len;
    if((len=(n+OCTLEN))<=LINELEN)
        printf("%o",c);
    else
        printf("\n%o",c);
    return len;
}
int main(){
    int c,cnum = 0;
    while((c=getchar())!=EOF){
        cnum=(c<32)?printoct(c,cnum):printnor(c,cnum);
        if(cnum>=LINELEN)
            cnum=cnum-LINELEN;
    }
    return 0;
}

P3

/**
 * Revise miniprintf to handle more of the other 
 * facilities of printf
 **/
#include <stdio.h>
#include <stdarg.h>
void miniprintf(char* fmt,...){
    va_list ap;
    char *p,*sval;
    int ival;
    double dval;
    va_start(ap, fmt); // make ap point ot 1st unnamed arg
    for (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
}
int main(){
    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>
void keep_reading(){
    char c;
    while((c=getchar())!='\n'||c!=EOF)
        ;
}
int mscanf(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 arg
    for (p = fmt; *p; p++){
        if (*p != '%'){
         c = getchar();
         if (c != *p){
             keep_reading();
             return 0;
     }
     else
         continue;
 }
    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!");
         return 0;
     }
    }
    va_end(ap);    // clean up when done
    return count;
}
int main(){
    int a;
    scanf("-%d",&a);//-114514
    printf("%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 114
double atof(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);
}
int main(){
    double sum,atof(char s[]);
    char s[MAXLINE];
    int x;
    sum = 0;
    while(scanf("%s",s)!=EOF)
        printf("\t%g\n",sum+=atof(s));
    return 0;
}

P6

/**
 * Write a program to compare two files, printing the first
 * line where thet differ.
 **/
#include <stdio.h>
#include <string.h>
#define MAXLINE 114
int main(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");
        return 0;
    }
    else if ((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);
                  return 0;
                 }
             }
            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");
    return 0;
}

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 114
int getline(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;
}
int main(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++;
               }
              }
          }
             else
              printf("error: could not open %s", *argv);
         }
     }
        else
         while (getline(line, MAXLINE) > 0){
             lineno++;
             if ((strstr(line, pattern) != NULL) != except){
              if (number)
                  printf("%ld:", lineno);
              printf("%s", line);
              found++;
             }
         }
    }
    else
        printf("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 81
int count_pages(FILE* f){
    int rows=0;
    char line[MAXLINE];
    while ((fgets(line,MAXLINE,f))!=NULL)
        rows++;
    rewind(f);
    return rows/PAGEROWS+1;
}
int main(int argc,char* argv[]){
    FILE* f;
    int pages = 0,rows,i;
    char line[MAXLINE];
    int count_pages(FILE *f);
    if(argc==1){
        printf("Not enough parameters!\n");
        return 0;
    }
    else
        while (--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);
         }
  return 0;
}

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>
int isupper(int c){
    return (c>='A'&&c<='Z');
}
int isupper(int c){
    return (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ",c)!=NULL);
}

第七章 完

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值