passing more than one file.

Discussion in 'C Programming' started by nickm687, Nov 9, 2006.

  1. nickm687

    nickm687 Guest

    Hi i have this code below and i need to modify it so i can pass more
    than one text file to it. any ideas? i am new to this. thanks in
    advance.
    Nick


    int main(int argc, char *argv[]) {
    FILE *f;
    int i;

    if (1 == argc) {
    f = stdin;
    } else {


    f = fopen(argv[1], "r");
    if (! f) {
    perror(argv[1]);
    fprintf( stderr
    , "Couldn't read file %s, dropping this file\n"
    , argv[1]);
    return errno;
    }
    }

    readFile(f);
    printInOrder((Displayer)showEntry,word_tree);
    return 0;
    }
     
    nickm687, Nov 9, 2006
    #1
    1. Advertisements

  2. nickm687

    Chris Dollin Guest

    I don't think you should modify it to work on multiple files until
    you have it working, which it clearly doesn't, since you've referred
    to several undeclared identifiers and forgotten to #include <stdio.h>.

    You should read a decent introductory C book, with special reference
    to the arguments to `main` and your choice of `for` or `while` loops.
    Start with a proglette which displays its command line arguments on
    the standard output.
     
    Chris Dollin, Nov 9, 2006
    #2
    1. Advertisements

  3. nickm687

    nickm687 Guest

    oh this is just an extract from code given to me. its a homework
    assignment and im stuck.

    this is it all.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <strings.h>
    #include <errno.h>
    #include "tree.h"

    /*******************************************************************************
    * Global variable for storing all the text
    * "last_word_end" marks the first free space
    */

    #define MAXSTRING (100 * 1024 * 1024)
    char info[MAXSTRING];
    char *last_word_end = info;


    /*******************************************************************************
    * Global variable for the word tree
    */

    Tree word_tree = NULL;


    /*******************************************************************************
    * Information kept on each word
    * a pointer to the address in storage
    * and the length of the word instance
    */

    typedef
    struct {
    char *word;
    int length;
    } WordS, *Word;


    /*******************************************************************************
    * Comparing word blocks
    * this give case-independent alphabetical order
    */
    int compareWords (Word alpha, Word beta) {
    int min = alpha->length <= beta->length ? alpha->length :
    beta->length;

    int alpha_cmp = strncasecmp(alpha->word, beta->word, min);

    if (0 != alpha_cmp) {
    return alpha_cmp;
    } else {
    return alpha->length - beta->length;
    }
    }

    /*******************************************************************************
    * adding a word item to the tree
    */

    void addWord (char *word) {
    Word w = malloc(sizeof(WordS));

    w->length = strlen(word);
    w->word = last_word_end;
    strncpy(last_word_end, word, w->length);
    last_word_end += w->length;
    strncpy(last_word_end, " ", 1);
    ++last_word_end;

    word_tree = insert((Comparator)compareWords, word_tree, (void *)w);
    return;
    }

    /*******************************************************************************
    * reading in a file
    */
    #define MAXLINE 256
    // maximum size for lines read in

    #define SEPARATORS " \t\n\r-:;,.!?()%\"'"
    // possible non-word characters

    void readFile(FILE *f) {
    char buf[MAXLINE];

    while (fgets(buf, MAXLINE, f)) {
    // for current line
    char *w = strtok(buf, SEPARATORS);
    if (w) {
    addWord(w);
    }
    while (w = strtok(NULL, SEPARATORS)) {
    addWord(w);
    }
    }
    }

    /*******************************************************************************
    * showEntry
    * show a line in the KWIC format
    * assumes caller will free this memory
    * shows some context either side of the target word
    */

    #define SCREEN_WIDTH 80

    char *showEntry(Word w) {
    char *p = (char *)malloc(SCREEN_WIDTH);
    char *q;
    q = w->word - 7 * SCREEN_WIDTH / 16;
    if (q < info) { q = info; } // question for you: why?
    strncpy(p, q, SCREEN_WIDTH - 1);
    p[SCREEN_WIDTH - 1] = '\0';
    return p;
    }


    /*******************************************************************************
    * showEntry
    * show a line in the KWIC format
    * assumes caller will free this memory
    * shows some context
    */


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


    if (1 == argc) {
    f = stdin;
    } else {


    f = fopen(argv, "r");
    if (! f) {
    perror(argv);
    fprintf( stderr
    , "Couldn't read file %s, dropping this file\n"
    , argv);
    return errno;

    }


    }

    readFile(f);
    printInOrder((Displayer)showEntry,word_tree);
    return 0;
    }
     
    nickm687, Nov 9, 2006
    #3
  4. nickm687

    apoelstra Guest

    Well, start by doing some design. What do you want to happen with
    multiple files? (What I assume is that you want each one to be
    printed off sequentially.) What happens when the filelist ends?
    (What you have is that if the filelist before it starts, use
    stdin.)

    So, start with what you've got. Make the first filename a special
    case because its absence is handled differently.

    Then, loop through argv[] until you hit NULL. (A useful thing
    that might not have been mentioned in class is that the last
    element of argv[] is guaranteed to be NULL.) With each file,
    try to open and do what you want with it.

    Also, when you can't open a file, don't bomb. Print a warning
    message to stderr and keep going. If no files are capable of
    being opened, then you can return an error value. The only
    portable value is EXIT_FAILURE, defined in <stdlib.h>. Anything
    else may work on your system, but could cause problems on
    others.
    You posted your complete code elsethread, so I'll comment over there
    on such things as, say, that cast that statistically should not be
    present.
     
    apoelstra, Nov 9, 2006
    #4
  5. nickm687

    apoelstra Guest

    1. Don't use globals.
    2. You can't statically allocate 100 megs. Use malloc(),
    and use a reasonable number. If you insist on using a
    fixed buffer, try 1024.
    Don't typedef pointers. It's confusing as hell.
    Why microoptimise with silly things like min here. Also,
    strncasecmp() is a non-standard function, and shouldn't
    be declared in any of the headers you included.
    You used two variables in this function that you didn't need.
    Uh... what? Oh, right, Word means a pointer. Hardly intuitive,
    especially as you're malloc()ing the size of a different type!

    [snip remaining unreadable code]
     
    apoelstra, Nov 9, 2006
    #5
  6. [...]

    I usually write a separate function which works on the filename
    passed, and then loop through argv:

    int main(int argc,char *argv[])
    {
    if ( argc == 1 )
    DoIt(NULL);
    else
    {
    while ( --argc )
    DoIt(*++argv);
    }
    return(EXIT_SUCCESS);
    }

    void DoIt(char *name)
    {
    FILE *f;
    if ( name == NULL )
    f = stdin;
    else
    {
    f = fopen(name,"r");
    if ( f == NULL )
    {
    /* handle error here */
    return;
    }
    }
    /* handle the file here */
    fclose(f);
    }

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Nov 9, 2006
    #6
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.