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

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

我的新站

P1

getch.c

/**
 * getch.c
 * written by swy
 */
#include <stdio.h>
#define BUFSIZE 114
char buf[BUFSIZE];
int bufp = 0;
int getch(){
    return (bufp>0)?buf[--bufp]:getchar();
}
void ungetch(int c){
    if(bufp>=BUFSIZE)
        printf("buffer overflow!\n");
    else
        buf[bufp++]=c;
}

getch.h

/**
 * getch.h
 * written by swy
 */
int getch();
void ungetch(int);

main.c

#include <stdio.h>
#include <ctype.h>
#include "getch.h"
#define SIZE 14
int getint(int* pn){
    int c, sign, c2;
    while (isspace(c = getch())) /* skip white space */
        ;
    if (!isdigit(c) && c != EOF && c != '+' && c != '-') {
        ungetch(c); /* it is not a number */
        return 0;
    }
    sign = (c == '-') ? -1 : 1;
    if (c == '+' || c == '-') {
        if (!isdigit(c2 = getch())) {
            ungetch(c2);
            ungetch(c);
            return 0;
        } else
            c = c2;
    }
    for (*pn = 0; isdigit(c); c = getch())
        *pn = 10 * *pn + (c - '0');
    *pn *= sign;
    if (c != EOF)
        ungetch(c);
    return c;
}
int main(void)
{
    int n, array[SIZE], r;
    for (n = 0; n < SIZE && (r = getint(&array[n])) != EOF; n++) {
        if (r)
            printf("you input a number: %d\n", array[n]);
        else
            printf("it is not a number.\n");
    }
    return 0;
}

P2

/**
 * getch.c
 * written by swy
 */
#include <stdio.h>
#define BUFSIZE 114
char buf[BUFSIZE];
int bufp = 0;
int getch(){
    return (bufp>0)?buf[--bufp]:getchar();
}
void ungetch(int c){
    if(bufp>=BUFSIZE)
        printf("buffer overflow\n");
    else
        buf[bufp++] = c;
}
/**
 * getch.h
 * written by swy
 */
int getch();
void ungetch(int);
/**
 * main.c
 * written by swy
 */
#include <stdio.h>
#include <ctype.h>
#include "getch.h"
#define SIZE 14
int getfloat(double *pn)
{
    double power, base, epower;
    int c, sign, c2, emark, exponent;
    while (isspace(c = getch())) /* skip white space */
        ;
    if (!isdigit(c) && c != EOF && c != '+' && c != '-') {
        ungetch(c); /* it is not a number */
        return 0;
    }
    sign = (c == '-') ? -1 : 1;
    if (c == '+' || c == '-') {
        if (!isdigit(c2 = getch())) {
            ungetch(c2);
            ungetch(c);
            return 0;
        } else
            c = c2;
    }
    for (*pn = 0.0; isdigit(c); c = getch())
        *pn = 10.0 * *pn + (c - '0');
    if (c == '.')
        c = getch();
    for (power = 1.0; isdigit(c); c = getch()) {
        *pn = 10.0 * *pn + (c - '0');
        power *= 10.0;
    }
    epower = 1;
    if (c == 'e' || c == 'E') {
        emark = c;
        c = getch();
        base = c == '-' ? 0.1 : 10.0;
        if (c == '+' || c == '-') {
            if (!isdigit(c2 = getch())) {
                ungetch(c2);
                ungetch(c);
            } else
                c = c2;
        } else if (!isdigit(c)){
            ungetch(c);
            ungetch(emark);
        }
        for (exponent = 0; isdigit(c); c = getch()) {
            exponent = 10 * exponent + (c- '0');
        }
        while (exponent-- > 0)
            epower *= base;
    }
    *pn *= sign / power * epower;
    if (c != EOF)
        ungetch(c);
    return c;
}
int main(void)
{
    int n;
    double array[SIZE], r;
    for (n = 0; n < SIZE && (r = getfloat(&array[n])) != EOF; n++) {
        if (r)
            printf("you input a number: %g\n", array[n]);
        else
            printf("it is not a number.\n");
    }
    return 0;
}

P3

#include <stdio.h>
#define MAXLINE 1024
void str_cat(char* s,char* t){
    while (*s)
        ++s;
    while (*s++ = *t++)
        ;
}
int getchars(char* s,int max){
    int c, i, l;
    for (i = 0, l = 0; (c = getchar()) != EOF && c != '\n'; ++i)
        if (i < max - 1) {
            *s++ = c;
            ++l;
        }
    *s = '\0';
    return l;
}
int main(void)
{
    char *s, *t;
    printf("input string s: \n");
    while (getchars(s, MAXLINE) == 0)
        ;
    printf("input string t: \n");
    while (getchars(t, MAXLINE) == 0)
        ;
    str_cat(s, t);
    printf("cat: %s\n", s);
    return 0;
}

P4

#include <stdio.h>
#define MAXLINE 1024
int strend(char* s,char* t){
    int sl, tl;
    sl = tl = 0;
    while (*s++)
        sl++;
    while (*t++)
        tl++;
    if (sl >= tl) {
        s -= tl;
        t -= tl;
        while (*s++ == *t++)
            if (!*s)
                return 1;
    }
    return 0;
}
int getchars(char* s,int max){
    int c, i, l;
    for (i = 0, l = 0; (c = getchar()) != EOF && c != '\n'; ++i)
        if (i < max - 1) {
            *s++ = c;
            ++l;
        }
    *s = '\0';
    return l;
}
int main(){
    char* s;
    char* t;
    printf("Please Enter:\n");
    while(getchars(s,MAXLINE)==0)
        ;
    while (getchars(t, MAXLINE) == 0)
        ;
    printf("string t is%s at the end of the string s.\n", strend(s, t) ? "" : " not");
    return 0;
}

P5

strncpy

#include <stdio.h>
void mstrncpy(char* s,char* t,int n){
    while(n-->0&&(*s++=*t++))
        ;
    *s = '\0';
}
int main(){
    char* t = "yeshouxianbei114514";
    char* s;
    mstrncpy(s,t,11);
    printf("%s\n",s);
    return 0;
}

strncat

/**
 * strncat.c
 * written by swy
 */
#include <stdio.h>
void mstrncat(char* s,char* t,int n){
    while(*s)
        ++s;
    while(n-->0&&*t){
        *(s++) = *(t++);//this line is buggy in Windows, but can work normally on the original Unix
    }
    *s = '\0';
}
int main(){
    char* s;
    char* t;
    s = "114514";
    t = "1919810";
    mstrncat(s,t,4);
    printf("%s\n",s);
    return 0;
}

strncmp

/**
 * strncmp
 * written by swy
 */
#include <stdio.h>
int mstrncmp(char* s,char* t,int n){
    for(;n-->0&&*s==*t;++s,++t)
        if(*s=='\0'||n==0)
            return 0;
    return *s-*t;
}
int main(){
    char* s;
    char* t;
    s = "114514";
    t = "1919810";
    printf("%d\n",mstrncmp(s,t,5));
    return 0;
}

P6

🐎🐴

P7

/**
 * lines.h
 * written by swy
 **/
#define MAXLINES 55
#define MAXLEN 108
int _getline(char* ,int);
int readlines(char* lineptr[],int nlines);
void writelines(char* lineptr[],int nlines);
/**
 * lines.c
 * written by swy
 **/
#include <stdio.h>
#include <string.h>
#include "lines.h"
int readlines(char* lineptr[],int maxlines){
    int len, nlines;
    char line[MAXLEN];
    nlines = 0;
    while ((len = _getline(line, MAXLEN)) > 0)
        if (nlines >= maxlines)
            return -1;
        else {
            line[len-1] = '\0'; /* delete newline */
            strcpy(lineptr[nlines++], line);
        }
    return nlines;
}
void writelines(char* lineptr[],int nlines){
    int i;
    for(i=0;i<nlines;i++)
        printf("%s\n",lineptr[i]);
}
int _getline(char s[],int max){
    int c, i, l;
    for (i = 0, l = 0; (c = getchar()) != EOF && c != '\n'; ++i)
        if (i < max - 1)
            s[l++] = c;
    if (c == '\n' && l < max - 1)
        s[l++] = c;
    s[l] = '\0';
    return l;
}
/**
 * qsort.h
 * written by swy
 **/
void qsort(char *lineptr[],int left,int right);
/**
 * qsot.c
 * written by swy
 * traitor Fang Fang biss
 **/
#include <string.h>
void qsort(char *v[],int left,int right){
    int i, last;
    void swap(char *v[], int i, int j);
    if (left >= right) /* do nothing if array contains */
        return; /* fewer than two elements */
    swap(v, left, (left + right)/2);
    last = left;
    for (i = left+1; i <= right; i++)
        if (strcmp(v[i], v[left]) < 0)
            swap(v, ++last, i);
    swap(v, left, last);
    qsort(v, left, last-1);
    qsort(v, last+1, right);
}
void swap(char *v[],int i,int j){
    char* tmp;
    tmp = v[i];
    v[i] = v[j];
    v[j] = tmp;
}
/**
 * main.c
 * written by swy
 **/
#include <stdio.h>
#include "lines.h"
#include "qsort.h"
char* lineptr[MAXLINES]
int main(void)
{
    int nlines; /* number of input lines read */
    int i;
    char s[MAXLINES][MAXLEN];
    for (i = 0; i < MAXLINES; ++i) {
        *(lineptr + i) = s[i];
    }
    if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
        qsort(lineptr, 0, nlines-1);
        writelines(lineptr, nlines);
        return 0;
    } else {
        printf("error: input too big to sort\n");
        return 1;
    }
}

P8

#include <stdio.h>
static char daytab[2][13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
int day_of_year(int year,int month,int day){
    int i,leap;
    if (month < 1 || month > 12 || day < 1)
        return 0;
    leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
    if (day > daytab[leap][month])
        return 0;
    for (i = 1; i < month; i++)
        day += daytab[leap][i];
    return day;
}
int month_day(int year,int yearday,int* pmonth,int* pday){
    int i, leap;
    leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
    if (yearday < 1 || yearday > (leap ? 366 : 365))
        return 0;
    for (i = 1; yearday > daytab[leap][i]; i++)
        yearday -= daytab[leap][i];
    *pmonth = i;
    *pday = yearday;
    return 1;
}
int main(){
    int year, month, day, yearday;
    int doy, pmonth, pday;
    year = 2012;
    month = 2;
    day = 29;
    doy = day_of_year(year, month, day);
    if (doy)
        printf("%d-%d-%d: day %dth of the year.\n", year, month, day, doy);
    else
        printf("%d-%d-%d: invalid!\n", year, month, day);
    year = 2012;
    month = 6;
    day = 31;
    doy = day_of_year(year, month, day);
    if (doy)
        printf("%d-%d-%d: day %dth of the year.\n", year, month, day, doy);
    else
        printf("%d-%d-%d: invalid!\n", year, month, day);
    year = 2012;
    yearday = 60;
    doy = month_day(year, yearday, &pmonth, &pday);
    if (doy)
        printf("day %dth of year %d is %d-%d.\n", yearday, year, pmonth, pday);
    else
        printf("day %dth of year %d do not exsits!\n", yearday, year);
    year = 2012;
    yearday = 367;
    doy = month_day(year, yearday, &pmonth, &pday);
    if (doy)
        printf("day %dth of year %d is %d-%d.\n", yearday, year, pmonth, pday);
    else
        printf("day %dth of year %d do not exsits!\n", yearday, year);
    return 0;
}

P9

#include <stdio.h>
static char daytab[2][13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
int day_of_year(int year,int month,int day){
    int i,leap;
    if(month<1||month>12||day<1)
        return 0;
    leap = year%4==0&&year%100!=0||year%400==0;
    if(day>*(*(daytab+leap)+month))
        return 0;
    for(i=1;i<month;i++)
        day+=*(*(daytab+leap)+i);
    return day;
}
int month_day(int year,int yearday,int* pmonth,int* pday){
    int i,leap;
    leap = year%4==0&&year%100!=0||year%400==0;
    if(yearday<1||yearday>(leap?366:365))
        return 0;
    for(i=1;yearday>*(*(daytab+leap)+i);i++)
        yearday-=*(*(daytab+leap)+i);
    *pmonth=i;
    *pday=yearday;
    return 1;
}
int main()
{
    int year, month, day, yearday;
    int doy, pmonth, pday;
    year = 2012;
    month = 2;
    day = 29;
    doy = day_of_year(year, month, day);
    if (doy)
        printf("%d-%d-%d: day %dth of the year.\n", year, month, day, doy);
    else
        printf("%d-%d-%d: invalid!\n", year, month, day);
    year = 2012;
    month = 6;
    day = 31;
    doy = day_of_year(year, month, day);
    if (doy)
        printf("%d-%d-%d: day %dth of the year.\n", year, month, day, doy);
    else
        printf("%d-%d-%d: invalid!\n", year, month, day);
    year = 2012;
    yearday = 60;
    doy = month_day(year, yearday, &pmonth, &pday);
    if (doy)
        printf("day %dth of year %d is %d-%d.\n", yearday, year, pmonth, pday);
    else
        printf("day %dth of year %d do not exsits!\n", yearday, year);
    year = 2012;
    yearday = 367;
    doy = month_day(year, yearday, &pmonth, &pday);
    if (doy)
        printf("day %dth of year %d is %d-%d.\n", yearday, year, pmonth, pday);
    else
        printf("day %dth of year %d do not exsits!\n", yearday, year);
    return 0;
}

P10

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#define NUMBER '0'
#define MAXVAL 114
int sp = 0;
double val[MAXVAL];
void push(double f){
    if (sp < MAXVAL)
        val[sp++] = f;
    else
        printf("stack overflow! %g\n", f);
}
double pop(){
    if(sp>0)
        return val[--sp];
    else{
        printf("stack empty!\n");
        return 0.0;
    }
}
int main(int argc, char *argv[])
{
    int type, c;
    double op2;
    printf("Usage example: expr 1 1 4 + p\n");
    while (--argc > 0) {
        if (!isdigit(c = **++argv) && strlen(*argv) == 1)
            type = c;
        else
            type = NUMBER;
        switch (type) {
        case NUMBER:
            push(atof(*argv));
            break;
        case '+':
            push(pop() + pop());
            break;
        case 'p':
            push(pop() * pop());
            break;
        case '-':
            op2 = pop();
            push(pop() - op2);
            break;
        case '/':
            op2 = pop();
            if (op2 != 0.0)
                push(pop() / op2);
            else
                printf("error: zero divisor\n");
            break;
        case '%':
            op2 = pop();
            if (op2 != 0.0)
                push(fmod(pop(), op2));
            else
                printf("error: zero divisor\n");
            break;
        default:
            printf("error: unknown command\n");
        break;
        }
    }
    printf("= %g\n", pop());
    return 0;
}

P11

entab

/**
 * entab.c
 * written by swy
 **/
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 1024
#define DEFAULTTABWIDTH 4
#define MAXTABSTOPS 10
int getchars(char* s,int max){
    int c, i, l;
    for (i = 0, l = 0; (c = getchar()) != EOF && c != '\n'; ++i)
        if (i < max - 1) {
            *s++ = c;
            l++;
        }
    *s = '\0';
    return l;
}
void entab(char* s1,char* s2,int w[]){
    int i,j,c,blanks,k;
    int blanksenough;
    i = 0;
    k = 0;
    while ((c = *s1) != '\0') {
        if (c == ' ') {
            blanksenough = 1;
            if (w[k] == 0)
                k = 0;
            blanks = w[k] - i % w[k];
            k++;
            for (j = 1; j < blanks; ++j){
                if (*(s1 + j) != ' ') {
                    blanksenough = 0;
                    break;
                }
            }
            if (blanksenough) {
                *s2++ = '\t';
                s1 += blanks;
                i += blanks;
            } else {
                *s2++ = c;
                i++;
                ++s1;
            }
        } else {
            *s2++ = c;
            i++;
            ++s1;
        }
    }
    *s2++ = '\0';
}
int main(int argc,char** argv){
    char s1[MAXLINE];
    char s2[MAXLINE];
    int w[MAXTABSTOPS + 1];
    int i, tab, j;
    if (argc > MAXTABSTOPS)
        argc = MAXTABSTOPS;
    j = 0;
    for (i = 2; i <= argc; ++i) {
        tab = atoi(*++argv);
        if (tab > 0)
            w[j++] = tab;
    }
    if (i == 2)
        w[j++] = DEFAULTTABWIDTH;
    w[j] = 0;
    printf("Usage example: entab 2 4 6\n");
    printf("Input some characters, then press enter:\n");
    while (getchars(s1, MAXLINE) == 0)
        ;
    entab(s1, s2, w);
    printf("entab result:\n%s\n", s2);
    return 0;
}

detab

/**
 * detab.c
 * written by swy
 **/
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 1024
#define DEFAULTTABWIDTH 4
#define MAXTABSTOPS 10
int getchars(char* s,int max){
    int c, i, l;
    for (i = 0, l = 0; (c = getchar()) != EOF && c != '\n'; ++i)
        if (i < max - 1) {
            *s++ = c;
            l++;
        }
    *s = '\0';
    return l;
}
void detab(char* s1,char* s2,int w[]){
    int j,l,c,blanks,k;
    l=0;
    k=0;
    while ((c = *s1++) != '\0') {
        if (c == '\t') {
            if (w[k] == 0)
                k = 0;
            blanks = w[k] - l % w[k];
            k++;
            for (j = 0; j < blanks; ++j) {
                *s2++ = ' ';
                l++;
            }
        } else {
            *s2++ = c;
            l++;
        }
    }
    *s2 = '\0';
}
int main(int argc,char** argv){
    char s1[MAXLINE];
    char s2[MAXLINE];
    int w[MAXTABSTOPS + 1];
    int i, tab, j;
    if (argc > MAXTABSTOPS)
        argc = MAXTABSTOPS;
    j = 0;
    for (i = 2; i <= argc; ++i) {
        tab = atoi(*++argv);
        if (tab > 0)
            w[j++] = tab;
    }
    if (i == 2)
        w[j++] = DEFAULTTABWIDTH;
    w[j] = 0;
    printf("Usage example: detab 2 4 6\n");
    printf("Input some characters, then press enter:\n");
    while (getchars(s1, MAXLINE) == 0)
        ;
    detab(s1, s2, w);
    printf("detab result:\n%s\n", s2);
    return 0;
}

P12

entab

/**
 * entab.c
 * written by swy
 **/
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 1024
#define DEFAULTSTARTCOL 1
#define DEFAULTTABWIDTH 8
int getchars(char* s,int max){
    int c, i, l;
    for (i = 0, l = 0; (c = getchar()) != EOF && c != '\n'; ++i)
        if (i < max - 1) {
            *s++ = c;
            l++;
        }
    *s = '\0';
    return l;
}
void entab(char* s1,char* s2,int col,int w){
    int i,j,c,blanks;
    int blanksenough;
    i = 0;
    while ((c = *s1) != '\0') {
        if (c == ' ' && i >= col - 1) {
            blanksenough = 1;
            blanks = w - i % w;
            for (j = 1; j < blanks; ++j){
                if (*(s1 + j) != ' ') {
                    blanksenough = 0;
                    break;
                }
            }
            if (blanksenough) {
                *s2++ = '\t';
                s1 += blanks;
                i += blanks;
            } else {
                *s2++ = c;
                i++;
                ++s1;
            }
        } else if (c == '\t') {
            *s2++ = c;
            i += w - i % w;
            ++s1;
        } else {
            *s2++ = c;
            i++;
            ++s1;
        }
    }
    *s2++ = '\0';
}
int main(int argc,char** argv){
    char s1[MAXLINE];
    char s2[MAXLINE];
    int m, n, m2, n2;
    m = DEFAULTSTARTCOL;
    n = DEFAULTTABWIDTH;
    while (--argc > 0) {
        argv++;
        if (**argv == '-') {
            if ((m2 = atoi(++*argv)) > 0)
                m = m2;
        } else if (**argv == '+') {
            if ((n2 = atoi(++*argv)) > 0)
                n = n2;
        }
    }
    printf("Usage example: entab -2 +8\n");
    printf("Input some characters, then press enter:\n");
    while (getchars(s1, MAXLINE) == 0)
        ;
    entab(s1, s2, m, n);
    printf("entab result:\n%s\n", s2);
    return 0;
}

detab

/**
 * detab.c
 * written by swy
 **/
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 1024
#define DEFAULTSTARTCOL 1
#define DEFAULTTABWIDTH 8
int getchars(char* s,int max){
    int c, i, l;
    for (i = 0, l = 0; (c = getchar()) != EOF && c != '\n'; ++i)
        if (i < max - 1) {
            *s++ = c;
            l++;
        }
    *s = '\0';
    return l;
}
void detab(char* s1,char* s2,int col,int w){
    int j, l, c, blanks;
    l = 0;
    while ((c = *s1++) != '\0') {
        if (c == '\t') {
            blanks = w - l % w;
            if (l >= col - 1) {
                for (j = 0; j < blanks; ++j) {
                    *s2++ = ' ';
                    l++;
                }
            } else {
                *s2++ = c;
                l += blanks;
            }
        } else {
            *s2++ = c;
            l++;
        }
    }
    *s2 = '\0';
}
int main(int argc,char** argv){
    char s1[MAXLINE];
    char s2[MAXLINE];
    int m,n,m2,n2;
    m = DEFAULTSTARTCOL;
    n = DEFAULTTABWIDTH;
    while (--argc > 0) {
        argv++;
        if (**argv == '-') {
            if ((m2 = atoi(++*argv)) > 0)
                m = m2;
        } else if (**argv == '+') {
            if ((n2 = atoi(++*argv)) > 0)
                n = n2;
        }
    }
    printf("Usage example: detab -2 +8\n");
    printf("Input some characters, then press enter:\n");
    while (getchars(s1, MAXLINE) == 0)
        ;
    detab(s1, s2, m, n);
    printf("detab result:\n%s\n", s2);
    return 0;
}

P13

/**
 * lines.h
 * written by swy
 **/
#define MAXLINES 55
#define MAXLEN 114
int _getline(char* ,int);
int readlines(char* lineptr[],int nlines);
int writelines(char* lineptr[],int nlines);
/**
 * alloc.h
 * written by swy
 **/
char *alloc(int);
void afree(char *p);
/**
 * lines.c
 * written by swy
 **/
#include <stdio.h>
#include <string.h>
#include "alloc.h"
#include "lines.h"
int readlines(char* lineptr[],int maxlines){
    int len, nlines;
    char *p, line[MAXLEN];
    nlines = 0;
    while ((len = _getline(line, MAXLEN)) > 0)
        if (nlines >= maxlines || (p = alloc(len)) == NULL)
            return -1;
        else {
            line[len-1] = '\0'; /* delete newline */
            strcpy(p, line);
            lineptr[nlines++] = p;
        }
    return nlines;
}
void writelines(char* lineptr[],int nlines){
    int i;
    for(i=0;i<nlines;i++)
        printf("%s\n",lineptr[i]);
}
int _getline(char s[],int max){
    int c, i, l;
    for (i = 0, l = 0; (c = getchar()) != EOF && c != '\n'; ++i)
        if (i < max - 1)
            s[l++] = c;
    if (c == '\n' && l < max - 1)
        s[l++] = c;
    s[l] = '\0';
    return l;
}
/**
 * alloc.c
 * written by swy
 **/
#include <stdio.h>
#define ALLOCSIZE 114514
static char allocbuf[ALLOCSIZE];
static char* allocp = allocbuf;
char* alloc(int n){
    if(allocbuf+ALLOCSIZE-allocp>=n){
        allocp+=n;
        return allocp-n;
    }else
        return 0;
}
void afree(char* p){
    if(p>=allocbuf&&p<allocbuf+ALLOCSIZE)
        allocp=p;
}
/**
 * main.c
 * written by swy
 **/
#include <stdio.h>
#include <stdlib.h>
#include "lines.h"
#define DEFAULTTAILNUM 10
char* lineptr[MAXLINES];
int main(int argc, char **argv)
{
    int nlines; /* number of input lines read */
    int tailnum, p;
    tailnum = DEFAULTTAILNUM;
    if (argc > 1 && **++argv == '-') {
        if ((p = atoi(++(*argv))) > 0)
            tailnum = p;
    }
    if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
        if (nlines < tailnum)
            tailnum = nlines;
        writelines(lineptr + nlines - tailnum, tailnum);
        return 0;
    } else {
        printf("error: input too big\n");
        return 1;
    }
}

P14

/**
 * lines.h
 * written by swy
 **/
#define MAXLINES 50
#define MAXLEN 114
int _getline(char* ,int);
int readlines(char* lineptr[],int nlines);
void writelines(char* linepter[],int nlines);
/**
 * alloc.h
 * written by swy
 **/
char* alloc(int);
void afree(char* p);
/**
 * alloc.c
 * written by swy
 **/
#include <stdio.h>
#define ALLOCSIZE 114514
static char allocbuf[ALLOCSIZE];
static char* allocp = allocbuf;
char* alloc(int n){
    if (allocbuf + ALLOCSIZE - allocp >= n) { /* it fits */
        allocp += n;
        return allocp - n; /* old p */
    } else /* not enough room */
        return 0;
}
void afree(char *p) /* free storage pointed to by p */
{
    if (p >= allocbuf && p < allocbuf + ALLOCSIZE)
        allocp = p;
}
/**
 * lines.c
 * written by swy
 **/
#include <stdio.h>
#include <string.h>
#include "alloc.h"
#include "lines.h"
int readlines(char* lineptr[],int maxlines){
    int len, nlines;
    char *p, line[MAXLEN];
    nlines = 0;
    while ((len = _getline(line, MAXLEN)) > 0)
        if (nlines >= maxlines || (p = alloc(len)) == NULL)
            return -1;
        else {
            line[len-1] = '\0'; /* delete newline */
            strcpy(p, line);
            lineptr[nlines++] = p;
        }
    return nlines;
}
void writelines(char* lineptr[],int nlines){
    int i;
    for(i=0;i<nlines;i++)
        printf("%s\n",lineptr[i]);
}
int _getline(char s[],int max){
    int c, i, l;
    for (i = 0, l = 0; (c = getchar()) != EOF && c != '\n'; ++i)
        if (i < max - 1)
            s[l++] = c;
    if (c == '\n' && l < max - 1)
        s[l++] = c;
    s[l] = '\0';
    return l;
}
/**
 * qsort.h
 * written by swy
 **/
void qsort(void* lineptr[],int left,int right,int (*comp)(void*,void*),int order);
/**
 * qsort.c
 * written by swy
 **/
#include <string.h>
void qsort(void* v[],int left,int right,int(*comp)(void*,void*),int order){
    int i, last;
    void swap(void *v[], int, int);
    if (left >= right) /* do nothing if array contains */
        return; /* fewer than two elements */
    swap(v, left, (left + right)/2);
    last = left;
    for (i = left+1; i <= right; i++)
        if (order && (*comp)(v[i], v[left]) < 0)
            swap(v, ++last, i);
        else if (!order && (*comp)(v[i], v[left]) > 0)
            swap(v, ++last, i);
    swap(v, left, last);
    qsort(v, left, last-1, comp, order);
    qsort(v, last+1, right, comp, order);
}
void swap(void* v[],int i,int j){
    void *temp;
    temp = v[i];
    v[i] = v[j];
    v[j] = temp;
}
/**
 * numcmp.h
 * written by swy
 **/
int numcmp(char*,char*);
/**
 * numcmp.c
 * written by swy
 **/
#include <stdlib.h>
int numcmp(char* s1,char* s2){
    double v1, v2;
    v1 = atof(s1);
    v2 = atof(s2);
    if (v1 < v2)
        return -1;
    else if (v1 > v2)
        return 1;
    else
        return 0;
}
/**
 * main.c
 * written by swy
 **/
#include <stdio.h>
#include "string.h"
#include "lines.h"
#include "qsort.h"
#include "numcmp.h"
char* lineptr[MAXLINES];
int main(int argc, char **argv){
    int nlines; /* number of input lines read */
    int numeric = 0; /* 1 if numeric sort */
    int order = 1; /* 1 if sorting in increasing order*/
    int c;
    while (--argc > 0 && *(*++argv) == '-') {
        while ((c = *++(*argv)) != '\0') {
            switch (c) {
                case 'n':
                    numeric = 1;
                    break;
                case 'r':
                    order = 0;
                    break;
                default:
                    break;
            }
        }
    }
    if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
        qsort((void**) lineptr, 0, nlines-1,
            (int (*)(void*,void*))(numeric ? numcmp : strcmp), order);
        writelines(lineptr, nlines);
        return 0;
    } else {
        printf("error: input too big to sort\n");
        return 1;
    }
}

P15

/**
 * alloc.h
 * written by swy
 **/
char* alloc(int);
void afree(char* p);
/**
 * alloc.c
 * written by swy
 **/
#include <stdio.h>
#include "alloc.h"
#define ALLOCSIZE 114514
static char allocbuf[ALLOCSIZE];
#define char* allocp = allocbuf;
char* alloc(int n){
    if (allocbuf + ALLOCSIZE - allocp >= n) { /* it fits */
        allocp += n;
        return allocp - n; /* old p */
    } else /* not enough room */
        return 0;
}
void afree(char* p){
    if (p >= allocbuf && p < allocbuf + ALLOCSIZE)
        allocp = p;
}
/**
 * lines.h
 * writen by swy
 **/
#define MAXLINES 50
#define MAXLEN 114
int _getline(char*,int);
int readlines(char* lineptr[],int nlines);
void writelines(char* lineptr[],int nlines);
/**
 * lines.c
 * written by swy
 **/
#include <stdio.h>
#include <string.h>
#include "alloc.h"
#include "lines.h"
int readlines(char* lineptr[],int maxlines){
    int len,nlines;
    char *p, line[MAXLEN];
    nlines = 0;
    while ((len = _getline(line, MAXLEN)) > 0)
        if (nlines >= maxlines || (p = alloc(len)) == NULL)
            return -1;
        else {
            line[len-1] = '\0'; /* delete newline */
            strcpy(p, line);
            lineptr[nlines++] = p;
        }
    return nlines;
}
void writelines(char* lineptr[],int nlines){
    int i;
    for(i=0;i<nlines;i++)
        printf("%s\n",lineptr[i]);
}
int _getline(char s[],int max){
    int c,i,l;
    for (i = 0, l = 0; (c = getchar()) != EOF && c != '\n'; ++i)
        if (i < max - 1)
            s[l++] = c;
    if (c == '\n' && l < max - 1)
        s[l++] = c;
    s[l] = '\0';
    return l;
}
/**
 * cmp.h
 * written by swy
 **/
int numcmp(char*,char*);
int strcmpignore(char*,char*);
/**
 * cmp.c
 * written by swy
 **/
#include <stdlib.h>
#include <ctype.h>
int numcmp(char* s1,char* s2){
    double v1,v2;
    v1 = atof(s1);
    v2 = atof(s2);
    if (v1 < v2)
        return -1;
    else if (v1 > v2)
        return 1;
    else
        return 0;
}
int strcmpignore(char* s1,char* s2){
    for (; tolower(*s1) == tolower(*s2); ++s1, ++s2)
        if (*s1 == '\0')
            return 0;
    return tolower(*s1) - tolower(*s2);
}
/**
 * qsort.h
 * written by swy
 **/
void qsort(void* lineptr[],int left,int right,int (*comp)(void*,void*),int order);
/**
 * qsort.c
 * written by swy
 **/
#include <string.h>
void qsort(void* v[],int left,int right,int (*comp)(void*,void*),int order){
    int i, last;
    void swap(void *v[], int, int);
    if (left >= right) /* do nothing if array contains */
        return; /* fewer than two elements */
    swap(v, left, (left + right)/2);
    last = left;
    for (i = left+1; i <= right; i++)
        if (order && (*comp)(v[i], v[left]) < 0)
            swap(v, ++last, i);
        else if (!order && (*comp)(v[i], v[left]) > 0)
            swap(v, ++last, i);
    swap(v, left, last);
    qsort(v, left, last-1, comp, order);
    qsort(v, last+1, right, comp, order);
}
void swap(void* v[],int i,int j){
    void* tmp;
    tmp = v[i];
    v[i] = v[j];
    v[j] = tmp;
}
/**
 * main.c
 * written by swy
 **/
#include <stdio.h>
#include "string.h"
#include "lines.h"
#include "qsort.h"
#include "cmp.h"
char* lineptr[MAXLINES];
int main(int argc, char **argv){
    int nlines; /* number of input lines read */
    int numeric = 0; /* 1 if numeric sort */
    int order = 1; /* 1 if sorting in increasing order */
    int ignorecase = 0; /* 1 if case insensitive */
    int c;
    while (--argc > 0 && *(*++argv) == '-') {
        while ((c = *++(*argv)) != '\0') {
            switch (c) {
                case 'n':
                    numeric = 1;
                    break;
                case 'r':
                    order = 0;
                    break;
                case 'f':
                    ignorecase = 1;
                    break;
                default:
                    break;
            }
        }
    }
    if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
        qsort((void**) lineptr, 0, nlines-1,
            (int (*)(void*,void*))(numeric ? numcmp : (ignorecase ? strcmpignore : strcmp)), order);
        writelines(lineptr, nlines);
        return 0;
    } else {
        printf("error: input too big to sort\n");
        return 1;
    }
}

P16

/**
 * alloc.h
 * written by swy
 **/
char* alloc(int);
void afree(char* p);
/**
 * alloc.c
 * written by swy
 **/
#include <stdio.h>
#define ALLOCSIZE 114514
static char allocbuf[ALLOCSIZE];
static char* allocp = allocbuf;
char *alloc(int n) {
    if (allocbuf + ALLOCSIZE - allocp >= n) { /* it fits */
        allocp += n;
        return allocp - n; /* old p */
    } else /* not enough room */
        return 0;
}
void afree(char* p){
    if(p>=allocbuf&&p<allocbuf+ALLOCSIZE)
        allocp = p;
}
/**
 * lines.h
 * written by swy
 **/
#define MAXLINES 50
#define MAXLEN 114
int _getline(char*,int);
int readlines(char* lineptr[],int nlines);
void writelines(char* lineptr[],int nlines);
/**
 * lines.c
 * written by swy
 **/
#include <stdio.h>
#include <string.h>
#include "alloc.h"
#include "lines.h"
int readlines(char* lineptr[],int maxlines){
    int len, nlines;
    char *p, line[MAXLEN];
    nlines = 0;
    while ((len = _getline(line, MAXLEN)) > 0)
        if (nlines >= maxlines || (p = alloc(len)) == NULL)
            return -1;
        else {
            line[len-1] = '\0'; /* delete newline */
            strcpy(p, line);
            lineptr[nlines++] = p;
        }
    return nlines;
}
void writelines(char* lineptr[],int nlines){
    int i;
    for(i=0;i<nlines;i++)
        printf("%s\n",lineptr[i]);
}
int _getline(char s[],int max){
    int c, i, l;
    for (i = 0, l = 0; (c = getchar()) != EOF && c != '\n'; ++i)
        if (i < max - 1)
            s[l++] = c;
    if (c == '\n' && l < max - 1)
        s[l++] = c;
    s[l] = '\0';
    return l;
}
/**
 * cmp.h
 * written by swy
 **/
int numcmp(char*,char*);
int strcmpignore(char*,char*);
/**
 * cmp.c
 * written by swy
 **/
#include <stdlib.h>
int numcmp(char* s1,char* s2){
    double v1, v2;
    v1 = atof(s1);
    v2 = atof(s2);
    if (v1 < v2)
        return -1;
    else if (v1 > v2)
        return 1;
    else
        return 0;
}
int strcmpignore(char* s1,char* s2){
    for (; tolower(*s1) == tolower(*s2); ++s1, ++s2)
        if (*s1 == '\0')
            return 0;
    return tolower(*s1) - tolower(*s2);
}
/**
 * qsort.h
 * written by swy
 **/
void qsort(void* lineptr[],int left,int right,int (*comp)(void*,void*),int order);
/**
 * qsort.c
 * written by swy
 **/
#include <string.h>
void qsort(void* v[],int left,int right,int (*comp)(void*,void*),int order){
    int i, last;
    void swap(void *v[], int, int);
    if (left >= right) /* do nothing if array contains */
        return; /* fewer than two elements */
    swap(v, left, (left + right)/2);
    last = left;
    for (i = left+1; i <= right; i++)
        if (order && (*comp)(v[i], v[left]) < 0)
            swap(v, ++last, i);
        else if (!order && (*comp)(v[i], v[left]) > 0)
            swap(v, ++last, i);
    swap(v, left, last);
    qsort(v, left, last-1, comp, order);
    qsort(v, last+1, right, comp, order);
}
void swap(void* v[],int i,int j){
    void* tmp;
    tmp = v[i];
    v[i] = v[j];
    v[j] = tmp;
}
/**
 * main.c
 * written by swy
 **/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "lines.h"
#include "qsort.h"
#include "cmp.h"
int isdirectory(char* s){
    return isdigit(*s)||isalpha(*s)||isspace(*s);
}
int strcompare(char* s1,char* s2){
    if (directory) {
        while(*s1 != '\0' && !isdirectory(s1))
            s1++;
        while(*s2 != '\0' && !isdirectory(s2))
            s2++;
        if (ignorecase) {
            while (tolower(*s1) == tolower(*s2)) {
                if (*s1 == '\0')
                    return 0;
                s1++;
                s2++;
                while(*s1 != '\0' && !isdirectory(s1))
                    s1++;
                while(*s2 != '\0' && !isdirectory(s2))
                    s2++;
            }
            return tolower(*s1) - tolower(*s2);
        } else {
            printf("dsdsd\n");
            while (*s1 == *s2) {
                if (*s1 == '\0')
                    return 0;
                s1++;
                s2++;
                while(*s1 != '\0' && !isdirectory(s1))
                    s1++;
                while(*s2 != '\0' && !isdirectory(s2))
                    s2++;
            }
            return *s1 - *s2;
        }
    } else {
        if (ignorecase) {
            return strcmpignore(s1, s2);
        } else {
            return strcmp(s1, s2);
        }
    }
}
int strcompare(char *s1, char *s2);
int isdirectory(char *s);
char *lineptr[MAXLINES]; /* pointers to text lines */
int ignorecase = 0; /* 1 if case insensitive */
int directory = 0; /* 1 if sorting in directory order */
int main(int argc, char **argv)
{
    int nlines; /* number of input lines read */
    int numeric = 0; /* 1 if numeric sort */
    int order = 1; /* 1 if sorting in increasing order*/
    int c, i;
    char *t;
    while (--argc > 0 && *(*++argv) == '-') {
        while ((c = *++(*argv)) != '\0') {
            switch (c) {
                case 'n':
                    numeric = 1;
                    break;
                case 'r':
                    order = 0;
                    break;
                case 'f':
                    ignorecase = 1;
                    break;
                case 'd':
                    directory = 1;
                    break;
                default:
                    break;
            }
        }
    }
    if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
        qsort((void**) lineptr, 0, nlines-1,
            (int (*)(void*,void*))(numeric ? numcmp : strcompare), order);
        writelines(lineptr, nlines);
        return 0;
    } else {
        printf("error: input too big to sort\n");
        return 1;
    }
}

第五章 完

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值