Страницы

Translate

суббота, 30 ноября 2013 г.

Exercise 7.9. Functions like isupper can be implemented to save space or to save time. Explore both possibilities



Exercise 7.9. Functions like isupper can be implemented to save space or to save time.
Explore both possibilities.



#include <ctype.h>

/* to save space */

int isupper(char c)
{
    if(c >= 'A' && c =< 'Z')
        return 1;
    else
        return 0;
}

/* to save time */

#define isupper(c) ((c) >= 'A' && (c) <= 'Z') ? 1 : 0


пятница, 29 ноября 2013 г.

Exercise 7.8. 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



Exercise 7.8. 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>
#include <string.h>

#define MAXFIELD 2 //maximum rows at the top and bottom of the page
#define MAXSTRING 60
#define MAXLINE 100
#define NAME 20

FILE *in, *out;
void fprint(char *pfile);
int headfile(char *pfile, int pageno);

int main(int argc, char *argv[])
{

    char file[NAME];
    char fileout[NAME]; //the output file
   
    if(argc == 1)
    {
        printf("ERROR, no arguments\n");
        return 1;
    }
    else
    {
        printf("Type the name of the output file: ");
        gets(fileout);
        out = fopen(fileout, "w");
        while(--argc > 0)
        {
            strcpy(file, *++argv);
            if((in = fopen(file, "r")) == NULL)
            {
                perror(file);
                return 1;
            }
            else
            {
                fprint(file);
                fclose(in);
            }
        }
    }
    fclose(out);
    return 0;
}

/* print the selected file */
void fprint(char *pfile)
{
    char line[MAXLINE];
    int lineno, pageno;

   
    lineno = pageno = 1;
    lineno = headfile(pfile, pageno);
    pageno++;
    while(!feof(in))
    {
        if(lineno == 1)
        {
            fprintf(out, "\f");
            lineno = headfile(pfile, pageno);
            pageno++;
        }
        fgets(line, MAXLINE-1, in);
        fputs(line,out);
        lineno++;
        if(lineno == (MAXSTRING - MAXFIELD))
            lineno = 1;
    }
    fprintf(out, "\f");
}

/* print header and blank lines */
int headfile(char *pfile, int pageno)
{
    int line = 0;
   
    while(line++ < MAXFIELD)
        fprintf(out, "\n");
    fprintf(out, "file %s, page - %d\n", pfile, pageno);
    line++;
    return line;
}

среда, 27 ноября 2013 г.

Exercise 7.7. 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, from the standard input.



Exercise 7.7. 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, from the standard input. Should the file name be printed when a matching  line is found?

#include <stdio.h>
#include <string.h>

#define MAXLINE 1000
#define NAME 20

FILE *in;
int except = 0;
int number = 0;
long lineno = 0;

int getline(char *line, int max);
void fstdin(char *line, char *pattern);
void ffile(FILE *fp, char *pattern, char *line, char *file_name);

/* find:  print lines that match pattern from 1st arg */
int main(int argc, char *argv[])
{
     char line[MAXLINE];
     char pattern[MAXLINE];
     char file[NAME];
;
     int c;
         
     while(--argc > 0 && (*++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;
                    break;
            }
    if(argc < 1)
    {
        printf("Usage: find -x -n pattern file...\n");
        return 1;
    }
    else
        strcpy(pattern, *argv);
    if (argc == 1) // read from stdin
        fstdin(line, pattern //search in the string
    else
        while(--argc != 0) //get file`s name
        {
            strcpy(file, *++argv);
            if((in = fopen(file, "r")) == NULL)
            {
                perror(file);
                return 1;
            }
            else
            {
                ffile(in, pattern, line,file); //search in the file
                fclose(in);
            }
        }
    return 0;
}

/* ffile: search in the file */

void ffile(FILE *in, char *pattern, char *line, char *file_name)
{
    while(!feof(in))
    {
        fgets(line, MAXLINE-1, in);
        lineno++;
        if((strstr(line, pattern) != NULL) != except)
        {
            printf("%s\n", file_name);
            if(number)
                printf("%ld: ", lineno);
            printf("%s", line);
        }
    }
}
       
/* fstdin: search in the string from standart input */
void fstdin(char *line, char *pattern)
{
    while(getline(line, MAXLINE) > 0)
    {
        lineno++;
        if((strstr(line, pattern) != NULL) != except)
        {
            if(number)
                printf("%ld: ", lineno);
            printf("%s", line);
        }
    }
}

/* getline: read the string, return the length */

int getline(char *line, int max)
{
    if(fgets(line, max, stdin) == NULL)
        return 0;
    else
        return strlen(line);
}


Result:


понедельник, 25 ноября 2013 г.

Exercise 7.6. Write a program to compare two files, printing the first line where they differ



Exercise 7.6. Write a program to compare two files, printing the first line where they differ.



#include <stdio.h>
#include <string.h>

#define MAXNAME 20
#define MAXLINE 100

FILE *first, *second;

int main()
{
    char f[MAXNAME], s[MAXNAME], str1[MAXLINE], str2[MAXLINE];
   
    printf("type the names of the compared files\n");
    printf("first: ");
    gets(f);
    printf("second: ");
    gets(s);
    if((first = fopen(f, "r")) == NULL)
    {
        perror(f);
        return 1;
    }
    else if((second = fopen(s, "r")) == NULL)
    {
        perror(s);
        return 1;
    }
    else
        printf("files open\n\n");
    while(!feof(first) && !feof(second))
    {
        fgets(str1, MAXLINE-1, first);
        fgets(str2, MAXLINE-1, second);
        if(strcmp(str1,str2) != 0)
             {
                printf("first different strings:\n\n");
                printf("%s\n%s\n", str1, str2);
                break;
            }
    }
    fclose(first);
    fclose(second);
    return 0;
}


Result:







понедельник, 18 ноября 2013 г.

Exercise 7.5. Rewrite the postfix calculator of Chapter 4 to use scanf and/or sscanf to do the input and number conversion.



Exercise 7.5. Rewrite the postfix calculator of Chapter 4 to use scanf and/or sscanf to do the input and number conversion.



#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define MAXOP 100 //max size of operand or operator
#define NUMBER '0' //signal that a number was found

int getop(char[]);
void push(double);
double pop(void);

/* reverse polish calculator */
int main()
{
    int type;
    double op2;
    char s[MAXOP];
   
    while((type = getop(s)) != EOF)
    {
        switch(type)
        {
            case NUMBER:
                push(atof(s));
                break;
            case '+':
                push(pop() + pop());
                break;
            case '*':
                push(pop() * pop());
                break;
            case '-':
                op2 = pop();
                push(pop() - op2);
                break;
            case '/':
                op2 = pop();
                if(op2 != 0)
                    push(pop() / op2);
                else
                    printf("error: zero devisior\n");
                break;
            case '%':
                op2 = pop();
                if(op2 != 0.0)
                    push(fmod(pop(), op2));
                else
                    printf("error: zero devisor\n");
                break;
            case '\n':
                printf("\t%.8g\n", pop());
                break;
            default:
                printf("error: unknown command %s\n", s);
                break;
        }
    }
    return 0;
}

#define MAXVAL 100 //maximum depth of val stack

double val[MAXVAL]; //value stack
int sp = 0; //next free stack position

/* push: push f into value stack */
void push(double f)
{
    if(sp < MAXVAL)
        val[sp++] = f;
    else
        printf("error: stack full, can`t push %g\n", f);
}

/* pop: pop and return top value from stack */
double pop(void)
{
    if(sp > 0)
        return val[--sp];
    else
    {
        printf("error: stack empty\n");
        return 0.0;
    }
}

#include <ctype.h>

/* getop: get next character ot numeric operand */
int getop(char s[])
{
    int i, c, rc;
    static char lastc[] = " ";
   
    c = lastc[0];
    lastc[0] = ' ';
    while((s[0] = c) == ' ' || c == '\t')
        if(scanf("%c", &c) == EOF)
            c = EOF;
    s[1] = '\0';
    if(!isdigit(c) && c != '.' && c != '-') // not a number
        return c;
    i = 0;
    if (c == '-')
    {
        scanf("%c", &c);
        rc = c;
        if(isdigit(c) || c == '.')
            s[++i] = c; //negative numbers
        else
            {
                if(rc != EOF)
                    lastc[0] = c;
                return '-';
            }
    }
    if(isdigit(c)) //collect integer part
        do
        {
            scanf("%c", &c);
            rc = c;
            if(!isdigit(s[++i] = c))
                break;
        } while(rc != EOF);
    if(c == '.') //collect fraction part
        do
        {
            scanf("%c", &c);
            rc = c;
            if(!isdigit(s[++i] = c))
                break;
        } while(rc != EOF);
    s[i] = '\0';
    if(rc != EOF)
        lastc[0] = c;
    return NUMBER;
}


Result:





Exercise 7.4. Write a private version of scanf analogous to minprintf




Exercise 7.4. Write a private version of scanf analogous to minprintf from the previous section.


#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>

#define ARRAYFMT 10

void minscanf(char *, ...);


/* minscanf: */

void minscanf(char *fmt, ...)
{
    va_list ap; //points to the next unnamed argument
    char *p, *sval;
    int *ival, i;
    unsigned *uval;
    double *dval;
    char arrayfmt[ARRAYFMT]; //array of characters
   
    i = 0;
    va_start(ap, fmt);//establishes for the first unnamed argument
    for(p = fmt; *p; p++)
    {
        if(*p != '%')
        {
            arrayfmt[i++] = *p;
            continue;
        }
        arrayfmt[i++] = '%';
        for(;*(p+1) && !isalpha(*(p+1)); i++)
            arrayfmt[i] = *++p;
        arrayfmt[i++] = *(p+1);//letter format
       
arrayfmt[i] = '\0';       
        switch (*++p) //letter format
        {
            case 'd':
            case 'i':
                ival = va_arg(ap, int *);
                scanf(arrayfmt, ival);
                break;
            case 'f':
                dval = va_arg(ap, double *);
                scanf(arrayfmt, dval);
                break;
            case 's':
                sval = va_arg(ap, char *);
                scanf(arrayfmt, sval);
                break;
            case 'o':
            case 'x':
            case 'X':
            case 'u':
            case 'e':
                uval = va_arg(ap, unsigned *);
                scanf(arrayfmt, uval);
                break;
        }
        i = 0;
    }
    va_end(ap);//clear, after finish}

суббота, 16 ноября 2013 г.

Exercise 7.2. Write a program that will print arbitrary input in a sensible way.



Exercise 7.2. 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>
#include <ctype.h>

#define MAXLINE 25 //maximum number of characters in line
#define OCTLEN 8 //length of the octal value

/*  print arbitrary input in a sensible way */
int main()
{
    int c, pos;
   
    pos = 0; //position in string    

    while((c = getchar()) != EOF)
        if(iscntrl(c) || isspace(c))
        {
            if(pos + OCTLEN < MAXLINE)
                pos = pos + OCTLEN;
            else
            {
                putchar('\n');
                pos = OCTLEN;
            }
            printf("
\\%03o", c);
            if(c == '\n')
            {
                pos = 0;
                putchar('\n');
            }
        }
        else
        {
            if(pos + 1 < MAXLINE)
                pos = pos + 1;
            else
            {
                putchar('\n');
                pos = 1;
            }
            putchar(c);
        }
    return 0;
}