Thread: CAT replication

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    69

    CAT replication

    I'm working on a replication of the Unix/Linux Cat utility, and I'm having some difficulty with its implementation. Right now, I'm using getopts to parse out the command line entry and then handling each argument one at a time. I'm reading it into a char array with fread, and I'm not sure if that's even the best way (looping with fgets, potentially?).

    Right now I'm trying to append $ to the end of each line, but instead it's replacing the \n with $, and I can't seem to figure out how to place a \n at the end. Any guidance on this and general suggestions would be much obliged.

    Code:
    char case_A( char buf[], int cap )
    {
            char *ptr;
            int i;
    
            for (i=0; i<cap; ++i)
            {
                    if((ptr = strchr(buf, '\n')))
                    {
                            *ptr = '$';
                    }
                    case_T( buf , cap);
            }
    
            return *buf;
    
    }
    the main:

    Code:
    int main(int argc, char * argv[])
    {
            int cap = 0;
            char choice;
            char *buf = malloc( cap * sizeof(char));
            FILE * fptr;
    
            fptr = fopen(argv[2], "r");
    
            do
            {
                    cap+=10;
                    buf = realloc(buf,  sizeof(char) * cap);
                    fread ( buf+cap-10, sizeof( char ), 10, fptr );
            }
            while(!feof(fptr));
    
            while (( choice = getopt (argc, argv, "AbeEnstTuv")) != -1)
            {
    
                      <switch statement for choice>

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Yep! looping with fgets, potentially is the way to go about it.
    And no you don't have to fit the entire file into a buffer, as with fread().
    Read each input line into a buffer and display it as per the command line options.

  3. #3
    Registered User
    Join Date
    Jan 2010
    Posts
    69
    how would i handle multiple commands like "./cat -vET test.txt", because that is how i wrote it first with fgets but then when i wanted to send it to another function that will do something else to it like number every output line or replace a tab with a "^I" it only read the last line it took in because fgets only reads line by line.

  4. #4
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by Dr Saucie View Post
    how would i handle multiple commands like "./cat -vET test.txt", because that is how i wrote it first with fgets but then when i wanted to send it to another function that will do something else to it like number every output line or replace a tab with a "^I" it only read the last line it took in because fgets only reads line by line.
    Parse and process the command line options for each line read instead of serializing calls to fgets() and getopt(), as in
    Code:
    while (read a line with fgets) {
        parse command line with getopt()
            process options with switch
                case 'T':
                    call a function to process option 'T'
                    break
                case 'v':
                    call a function to process option 'v'
                    break
                .
                .
                .
    }
    Last edited by itCbitC; 03-21-2010 at 10:11 PM. Reason: pseudo-code

  5. #5
    Registered User
    Join Date
    Jan 2010
    Posts
    69
    ok i get what mean now, ill finish it this way but i want to try and figure how to append it to the end of a line. Thanks brawski

  6. #6
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    As the input line is buffered [choose a big buffer] replace the terminating newline with the end-of-line anchor "$" and a newline.

  7. #7
    Registered User
    Join Date
    Feb 2010
    Posts
    11
    How are you intending to deal with the '-u' option if you're using fgets()...?

  8. #8
    Registered User
    Join Date
    Jan 2010
    Posts
    69
    '-u' is ignored..... is there an easy way to append numbers to the front of my char buf?

  9. #9
    Registered User
    Join Date
    Jan 2010
    Posts
    69
    alright so I figured out how to append things (temp char array, sprintf a counter into it, strcat it onto the buf), and so far my code hits all the cases that are necessary, but it only does it to the first line. After that, it just spits out the rest of the buf.

    Code:
     while( fgets(buf, 1500, fptr) != NULL)
            {
                    while((choice = getopt ( argc, argv, "AbeEnstTuv")) != -1)
                    {
                            switch(choice)
                            {
                                    case 'A': /*Shows all equivalent to -vET*/
                                    case_A( buf , cap );
                                    break;
    
                                    case 'b':
                                    case_b(buf);
                                    break;
    
                                    case 'e':
                                    printf("equivalent to -vE\n");
                                    break;
    
                                    case 'E':
                                    case_E( buf );
                                    break;
    
                                    case 'n': /*numbers all output lines*/
                                    break;
    
                                    case 's':
                                    printf("supress repeated empty output lines\n");
                                    break;
    
                                    case 't':
                                    printf("equivalent to -vT\n");
                                    break;
    
                                    case 'T': /*display TAB character as ^I*/
                                    case_T( buf , cap);
                                    break;
    
                                    case 'u':
                                    printf("ignored\n");
                                    break;
    
                                    case 'v':
                                    printf("use ^ and M- notation,except for LFD and TAB\n");
                                    break;
                            }
                    }
                    printf("%s\n", buf);
            }
            fclose(fptr);
            return 0;
    i know I need to loop it while fgets is reading (or while not EOF?), but if I parse on the outside another slew of issues arise. Any logic suggestions/recommendations?

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Dr Saucie View Post
    alright so I figured out how to append things (temp char array, sprintf a counter into it, strcat it onto the buf), and so far my code hits all the cases that are necessary, but it only does it to the first line. After that, it just spits out the rest of the buf.

    Code:
     while( fgets(buf, 1500, fptr) != NULL)
            {
                    while((choice = getopt ( argc, argv, "AbeEnstTuv")) != -1)
                    {
                            switch(choice)
                            {
                                    case 'A': /*Shows all equivalent to -vET*/
                                    case_A( buf , cap );
                                    break;
    
                                    case 'b':
                                    case_b(buf);
                                    break;
    
                                    case 'e':
                                    printf("equivalent to -vE\n");
                                    break;
    
                                    case 'E':
                                    case_E( buf );
                                    break;
    
                                    case 'n': /*numbers all output lines*/
                                    break;
    
                                    case 's':
                                    printf("supress repeated empty output lines\n");
                                    break;
    
                                    case 't':
                                    printf("equivalent to -vT\n");
                                    break;
    
                                    case 'T': /*display TAB character as ^I*/
                                    case_T( buf , cap);
                                    break;
    
                                    case 'u':
                                    printf("ignored\n");
                                    break;
    
                                    case 'v':
                                    printf("use ^ and M- notation,except for LFD and TAB\n");
                                    break;
                            }
                    }
                    printf("%s\n", buf);
            }
            fclose(fptr);
            return 0;
    i know I need to loop it while fgets is reading (or while not EOF?), but if I parse on the outside another slew of issues arise. Any logic suggestions/recommendations?
    It's been a while since I've used getopt, but can you use it more than once? (I.e., the second time through the loop, getopt just throws up its hands, since there's no more options to be processed, right?) So just do getopt outside the loop, and remember the answer.

    EDIT: From the man page of getopt on my system:
    Quote Originally Posted by man getopt
    In order to use getopt() to evaluate multiple sets of arguments, or to
    evaluate a single set of arguments multiple times, the variable optreset
    must be set to 1 before the second and each additional set of calls to
    getopt(), and the variable optind must be reinitialized.
    Last edited by tabstop; 03-22-2010 at 09:14 PM.

  11. #11
    Registered User
    Join Date
    Jan 2010
    Posts
    69
    Quote Originally Posted by tabstop View Post
    It's been a while since I've used getopt, but can you use it more than once? (I.e., the second time through the loop, getopt just throws up its hands, since there's no more options to be processed, right?) So just do getopt outside the loop, and remember the answer.

    EDIT: From the man page of getopt on my system:

    I appreciate the help tabstop - this fixed it! I had to throw a optind = 1 near the end and it worked out wonderfully.

    I have the -v tag still left to write, and am pretty unclear on exactly what it does. Do you have any good sources that explain it?

    Thanks again.

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    man cat says:
    Quote Originally Posted by man cat
    -v, --show-nonprinting
    use ^ and M- notation, except for LFD and TAB
    ^ notation is for nonprintable characters 1 through 26 (1 is ^A through 26 is ^Z). Don't remember the specifics of M- notation.

  13. #13
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by Dr Saucie View Post
    i know I need to loop it while fgets is reading (or while not EOF?), but if I parse on the outside another slew of issues arise. Any logic suggestions/recommendations?
    Alternatively, first process the options to cat and then read in the file line-by-line.
    This method processes the "-u" option for unbuffered output and handle errors better.

  14. #14
    Registered User
    Join Date
    Feb 2010
    Posts
    11
    Quote Originally Posted by Dr Saucie View Post
    '-u' is ignored..... is there an easy way to append numbers to the front of my char buf?
    With all respect, '-u' is the only option that POSIX insists that cat supports. You can, of course, choose to program your utility any old way you like, but why are you wanting to repeat the abuse of UNIX that the GNUtards (and others) have inflicted upon us?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Question about File Input
    By ChristianTool in forum C Programming
    Replies: 12
    Last Post: 04-25-2004, 02:40 PM
  2. HowTo (give your cat a pill)
    By Carlos in forum A Brief History of Cprogramming.com
    Replies: 14
    Last Post: 01-21-2004, 04:20 PM
  3. Deleting classes, or is it impossible?
    By Lariumentiko in forum C++ Programming
    Replies: 13
    Last Post: 02-02-2003, 04:26 PM
  4. A Cat and a Dog
    By da_fall_guy in forum C++ Programming
    Replies: 10
    Last Post: 07-24-2002, 09:20 AM
  5. Cat hates getting a bath
    By Troll_King in forum A Brief History of Cprogramming.com
    Replies: 28
    Last Post: 10-23-2001, 08:15 PM