Like Tree1Likes
  • 1 Post By AndiPersti

Exercise 5-17 k&R

This is a discussion on Exercise 5-17 k&R within the C Programming forums, part of the General Programming Boards category; Add a field-searching capability, so sorting may bee done on fields within lines, each field sorted according to an independent ...

  1. #1
    Registered User
    Join Date
    Jun 2013
    Posts
    3

    Exercise 5-17 k&R

    Add a field-searching capability, so sorting may bee done on fields within lines, each field sorted according to an independent set of options. (The index for this book was sorted with -df for the index category and -n for the page numbers.)
    This is the code i was following (Tondo's Book)
    Code:
    //main.c
    #include <stdio.h>
    #include <ctype.h>
    
    
    #define NUMERIC 1
    #define DECR 2
    #define FOLD 4
    #define DIR 8
    #define LINES 100
    
    
    int charcmp(char *, char *);
    void error(char *);
    int numcmp(char *, char *);
    void readargs(int argc, char *argv[]);
    int readlines(char *lineptr[], int maxlines);
    void qusort(void *v[],int left, int right,int (*comp)(void *, void *));
    void writelines(char *lineptr[], int nlines, int decr);
    
    
    char option = 0;
    int pos1 = 0;
    int pos2 = 0;
    int main(int argc, char *argv[])
    {
        char *lineptr[LINES];
        int nlines;
        int rc = 0;
        
        readargs(argc, argv);
        if((nlines = readlines(lineptr, LINES)) > 0 ) {
            if (option & NUMERIC)
                qusort((void **) lineptr, 0 , nlines - 1,
                            (int (*) (void *, void *)) numcmp);
            else
                qusort((void **) lineptr, 0, nlines-1,
                            (int (*)(void *,void *)) charcmp);
            writelines(lineptr,nlines,option & DECR);
        } else {
                printf("input too big to sort \n");
                rc = -1;
        }
        return rc;
    }
    
    
    void readargs(int argc, char *argv[])
    {
        int c;
        int atoi(char *);
        
        while((--argc>0) && (((c = (*++argv)[0])=='-')||(c=='+')))
        {
            if (c=='-' && !isdigit(*(argv[0]+1)))
                while((c = *++argv[0]))
                    switch(c) {
                    case 'd':
                        option |= DIR;
                        break;
                    case 'f':
                        option |= FOLD;
                        break;
                    case 'n':
                        option |= NUMERIC;
                        break;
                    case 'r':
                        option |= DECR;
                        break;
                    default:
                        printf("sort: illegal option %c\n", c);
                        error("Usage: sort -dfnr [+pos1] [-pos2]");
                        break;
                    }
            else if (c == '-')
                pos2 = atoi(argv[0]+1);
            else if ((pos1 = atoi(argv[0]+1)) < 0)
                error("Usage: sort -dfnr [+pos1] [-pos2]");
        }
        if (argc || pos1 > pos2)
            error("Usage: sort -dfnr [+pos1] [-pos2]");
    }
    
    
    void writelines(char *lineptr[], int nlines, int decr)
    {
        int i;
        if(decr)
            for(i = nlines - 1; i >=0; i--)
                printf("%s\n",lineptr[i]);
        else
            for(i = 0;i <nlines; i++)
                printf("%s\n",lineptr[i]);
    }
    
    
    #include <string.h>
    #define MAXLEN 1000
    int getline(char *, int);
    char *alloc(int);
    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+1)) == NULL)
                return -1;
            else {
            line[len] = '\0'; /* delete newline */
            strcpy(p, line);
            lineptr[nlines++] = p;
            }
            return nlines;
    }
    
    
    int getline(char *s, int lim)
    {
        int c;
        char *t = s;
        while(--lim > 0 && (c = getchar()) != EOF && c != '\n')
            *s++ = c;
        *s = '\0';
        return s - t;
    }
    
    
    #define ALLOCSIZE 10000 /* size of available space */
    static char allocbuf[ALLOCSIZE]; /* storage for alloc */
    static char *allocp = allocbuf; /* next free position */
    char *alloc(int n) /* return pointer to n characters */
    {
        if (allocbuf + ALLOCSIZE - allocp >= n) 
        { /* it fits */
            allocp += n;
            return allocp - n; /* old p */
        } 
        else /* not enough room */
            return 0;
    }
    
    
    void swap(void *v[], int i, int j);
    void qusort(void *v[], int left, int right, int(*comp)(void *, void *))
    {
         int i, last;
         void swap(void *v[], int, int);
    
    
         if(left >= right)
            return;
    
    
         swap(v, left, (left + right) / 2);
         last = left;
         for(i = left + 1; i <= right; i++) 
            if((*comp)(v[i], v[left]) < 0)
               swap(v, ++last, i);
         swap(v, left, last);
         qusort(v, left, last - 1, comp);
         qusort(v, last + 1, right, comp);
    }
    
    
    void swap(void *v[], int i, int j)
    {
            void *temp;
            temp = v[i];
            v[i] = v[j];
            v[j] = temp;
    }
    //numcmp.c
    #include <math.h>
    #include <ctype.h>
    #include <string.h>
    
    
    #define MAXSTR 100
    
    
    void substr(char *s, char *t, int maxstr);
    
    
    int numcmp(char *s1, char *s2)
    {
        double v1,v2;
        char str[MAXSTR];
        
        substr(s1, str, MAXSTR);
        v1 = atof(str);
        substr(s2,str,MAXSTR);
        v2 = atof(str);
        if(v1 < v2)
            return -1;
        else if (v1 > v2)
            return 1;
        else
            return 0;
    }
    
    
    #define FOLD    4
    #define DIR        8
    int charcmp(char *s, char *t)
    {
        char a, b;
        int i, j, endpos;
        extern char option;
        extern int pos1, pos2;
        int fold = (option & FOLD) ? 1 : 0;
        int dir = (option & DIR) ? 1 : 0;
        
        i = j = pos1;
        if(pos2 > 0)
            endpos = pos2;
        else if((endpos = strlen(s)) > strlen(t))
            endpos = strlen(t);
        do {
                if(dir) {
                    while(i < endpos && !isalnum(s[i]) && s[i] != ' ' && s[i] != '\0')
                    i++;
                    while(j < endpos && !isalnum(t[j]) && t[j] != ' ' && t[j] != '\0')
                    j++;
                }
                if (i <endpos && j < endpos) {
                a = fold ? tolower(s[i]): s[i];
                i++;
                b = fold ? tolower(t[j]): t[j];
                j++;
                if(a == b && a == '\0')
                    return 0;
                }
            } while(a == b && i < endpos && j < endpos);
            return a - b;
    }
    //substr.c
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    
    
    void error(char *);
    
    
    void substr(char *s, char *str)
    {
        int i, j, len;
        extern int pos1, pos2;
        
        len = strlen(s);
        if(pos2 > 0 && len > pos2)
            len = pos2;
        else if(pos2 > 0 && len < pos2)
            error("substr: string too short");
        for(j = 0, i = pos1; i < len; i++, j++)
            str[j] = s[i];
        str[j] = '\0';
    }
    void error(char *s)
    {
        printf("%s \n", s);
        exit(1);
    }
    gcc main.c numcmp.c substr.c -Wall -Werror -pedantic -g -o SortFields.exe
    no errors on compilation.

    My problem lies on how to use the arguments on locating the position of the field to be sorted. I am following this link c - K&R Task Exercise 5.17 - Stack Overflow but it doesn't discuss what argument to use to sort the second field.

    The instruction "Usage: sort -dfnr [+pos1] [-pos2]" - i don't know how to use this, I only know -dfnr since i have done the previous exercises.The problem lies with what pos1 and pos2 is and use this to sort any field position i want. I think you should look at the readargs() function because i think that's where the problem lies.
    Last edited by BinaryProgamer; 06-21-2013 at 05:58 AM.

  2. #2
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by BinaryProgamer View Post
    gcc main.c numcmp.c substr.c -Wall -Werror -pedantic -g -o SortFields.exe
    no errors on compilation.
    You should get at least a warning that atof() isn't declared properly in numcmp.c.

    And this also looks strange:
    Code:
    //numcmp.c
    void substr(char *s, char *t, int maxstr);
    ...
    //substr.c
    void substr(char *s, char *str)
    Isn't there a parameter to much in numcmp.c?

    Anyways, if I fix that I get:
    Code:
    $ cat test.txt
    apple  9 3
    pear   2 8
    orange 6 4
    banana 1 4
    $ ./foo -n +7 -8 < test.txt
    banana 1 4
    pear   2 8
    orange 6 4
    apple  9 3
    $ ./foo -n +9 -10 < test.txt
    apple  9 3
    banana 1 4
    orange 6 4
    pear   2 8
    So, "pos1" is the start of the field and "pos2" one past the end which should also be obvious after reading charcmp() and substr().

    Bye, Andreas
    BinaryProgamer likes this.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. exercise in c
    By hugoguan in forum C Programming
    Replies: 1
    Last Post: 11-30-2010, 03:32 AM
  2. Help exercise!
    By sanhthai in forum C++ Programming
    Replies: 10
    Last Post: 09-22-2009, 12:07 PM
  3. Exercise 2-6 K&R help
    By allix in forum C Programming
    Replies: 19
    Last Post: 08-18-2006, 09:25 AM
  4. Exercise
    By bumfluff in forum C++ Programming
    Replies: 15
    Last Post: 04-21-2006, 12:18 PM
  5. Help with K&R Exercise 1.13
    By Yannis in forum C Programming
    Replies: 2
    Last Post: 09-21-2003, 02:51 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21