Thread: Reading in a filename from shell

  1. #1
    Registered User
    Join Date
    Oct 2010
    Posts
    8

    Reading in a filename from shell

    I am reading in multiple variables from the shell and my program needs to find an input file from the jumble of variables passed in.

    a command in the shell can look like this:
    Code:
    newgrep [-i] searchstring sourcefile [-o targetfile]
    I was reading in by arithmetic ( argc - 1 ) and i would find the file name that way. Now that I have my program working and doing what is it supposed to, I'm making some fixes that make it do it the WAY it is supposed to.

    So the problem I present is how do I find a file that exists from my 2-D vector array, argv.

    Code:
    #include "newgrep.h"
    
    int main ( int argc, char * argv[] ){
    
      char  strArg [argc] [81], // Argument 2-D Char array
            str [50] [81], // Strings from Input File
            strOut [50] [81], // Back-up of str array before tokenization
            tokArr [100] [10], // Holds tokens for output
            outFile [81], // output file
            keyword [81], // word for string compare
            * filename, // File argument in argv(a.k.a. file)
            * token,  // pointer to follow strtok
            option;  // Option for switch statement
    
      int   i, // Loop Counter
            j, // Argument String elements, re-used for loop counter
            k, // Arg string counter, re-used for loop counter
            l, // Used to count token string
            lines, // number of lines in file
            occur = 0,  // how many times keyword occurs
            boolI = 0,  // Boolean value for option I
            boolO = 0;  // Boolean value for option O
            
      FILE * fp, // File Pointer for input file (3rd arg)
           * ofp; // File pointer for output file
    
      // Copy String of arguments to strArg
      for( i = 0; i < argc; i++){
        strcpy ( strArg[i], argv[i] );
      }
    
    /*  
      // Echo number of arguments passed into main
      if( argc == 1 ){
        printf ( "\nThis program has received one argument.\n\n" );
      }else{
        printf ( "\nThere were %d arguments passed to args.\n\n", argc);
      }
    */
      
      // Finds Option elements
      for( i = 0 ; i < argc ; i++){ // Loop thru arguments, re-init i
        if ( strchr(strArg[i], '-') != NULL ){ // Look for '-' char, continue if '-' char
          j =  strlen(strArg[i]); // Set j for max loop cycles
          for( k = 0 ; k < j ; k++){ // for loop goes through element i's char array 
            option = strArg[i][k]; // set current char to option
            switch( option ){ // test for either 'i'|'I' or 'o'|'O'
    
              case 'i':
              case 'I':
                boolI = 1;
                break;
    
              case 'o':
              case 'O':
                boolO = 1;
                strcpy(outFile, argv[i+1]);
                break;
    
              default:
                break;
            }
          }
        }
      }
    
      // ##################
      // #### File Operations ####
      // ##################
    
      // Sets filename to its own character array
      filename = strArg[(argc - 1)];
    
    /* DEBUGGING: Prints filenames
      printf("argc is %d\n", argc);
      printf("raw filename is %s\n", strArg[argc-1]);
      printf("filename is %s\n", filename);
    */
      
      // Check to see if file is valid
      if ( (fp=fopen (filename, "r") ) == NULL){
          fprintf ( stderr, "File IO: Unable to open %s!\n",
          filename);
          exit(1);
        }
      // Read in until end of file
      lines = 0;
      while ( fgets(str[lines++], 81, fp) != NULL ){
      }
      
      //Housekeeping
      fclose(fp);
    
      // ####################
      // #### String Processing ####
      // ####################
      
      //Promt user for word to search for
      printf("Enter a keyword: ");
      scanf("%s", keyword);
      printf("You entered: %s\n", keyword);
    
      // Make back-up of str for later output
      for( i = 0 ; i < lines; i++){
        strcpy(strOut[i], str[i]);
      }
    
      
      i = j = k = l = 0; // Re-initialize loop variables
      
      // upper-case str for -o option
      if( boolI == 1 ){
        for( i = 0; i < lines; i++){
          for( j = 0; j < strlen(str[i]); j++){
            str[i][j]=toupper(str[i][j]);
          }
        }
        for( k = 0; k < strlen(keyword); k++)
          keyword[k]=toupper(keyword[k]);
      }
      
      // Tokenization loop
      for(i = 0 ; i < lines ; i++){ // Loop thru lines first to last
        token = strtok(str[i], " ,.-"); // priming token
        while(token){
          if( strncmp(token, keyword, strlen(keyword)) == 0){
          occur ++; // Count match
          }
          for(j = 0; j < strlen(token) ;j++ ){
            tokArr[l][j] = token[j];
          }  
          l++;
          token = strtok(NULL, " ,.-\n"); // continue tokenizing
        }
      }
      
      // #############
      // #### Output ####
      // #############
      if(boolO == 1){
        ofp=fopen ("output.dat", "w");
        if (ofp!=NULL){
          for(i=1; i < l - 1 ; i++){
            fprintf(ofp, "%s ", tokArr[i]);
          }
          fprintf(ofp, "%s.\n", tokArr[ l - 1 ]);
          fprintf(ofp, "\nThere are %d occurences of the keyword [%s].\n",
            occur, keyword);
          fclose (ofp);
          printf("Successful Write to output.dat\n");
        }
    
      }else{
        for(i=1; i < l - 1; i++){
          printf("%s ",tokArr[i]);
        }
        printf("%s.\n", tokArr[ l - 1 ]);
        printf("\nThere are %d occurences of the word [%s].\n", occur, keyword);
      }
      return(0);
    }
    A couple notes:
    1. newgrep.h contains(forum notes marked with "--")
    Code:
    /*********************************************************************
      Name: <DELETED>
      Last Revision: 10/18/10
      Desc: This program searches a file for occurences of a string. This
      program is somewhat similar to the Unix grep utility, thus is called
      newgrep.
    *********************************************************************/
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    #include <ctype.h>
    
    -- Failed attempts at splitting up the program for modularity
    -- Passing 2-D char arrays proved too difficult
    /*
    freadIn(char* , char** , int, int, char* );
    ftokPro(char** , char** , char** , int, int *);
    */
    2. Any notes on bad coding habits that should be stopped PDQ are helpful!

  2. #2
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    I'd use getopt function.
    Btw, what you have now is just string search program. There's nothing regex involved...
    Maybe you may want to use posix regex

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    First, ------------->Welcome to the forum, Daerogami!

    You did input, processing, and output, all in the SAME function?

    Break them up into at least two or three functions!

    Second, show some examples of the input you need to sort through. I know very little about Linux and Grep, (but I do like Ubuntu and Arch distro's).

    In this case, the specifics are all important, though. EXACTLY what is your input you have, and what is your program failing to find?

    Things like that.

    Just pseudo code is fine, if you prefer. It's the logic that is important, not the actual code. First the logic gets sorted out basically, ===> then the code.

  4. #4
    Registered User
    Join Date
    Oct 2010
    Posts
    8
    Thanks for the warm welcome Adak.

    I wanted to break them up into functions(and my assignment requires it), but I couldn't figure out how to pass by reference a 2-D character array from main.

    As far as input is concerned, It is probably going to be in sentence format, i.e.:
    Code:
    Hello world. I am a text file with words.
    I have multiple lines and might have
    numbers such as 7, 6, or 10.
    My program isn't failing to find anything, in a literal sense, my program does what it is supposed to. Its finding the keywords, but I made the mistake of prompting the user for
    a keyword and not have the user pass it in from the shell.

  5. #5
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    You're pretty close as it it.

    First a few ideas.
    1. No need to copy argv since you're not modifying it. You can use it directly, just like you do argc.
    2. I'd just check (argv[i][0] == '-') directly instead of using strchr. This will fail if you have an input file or string with a dash in the middle of it, for one thing.
    3. What happens if you run your program with "myprog -o"? Check that argv[i+1] is valid before copying from it.
    4. Be consistent on whether you're going to use pointers to argv[] for filenames or copy them into your own buffer. You should be using the same method for filename and ofile - pick one or the other since consistency will help later on.

    Right now you handle arguments with dashes with no problem. You need to add an else to your check for cases where you see an argument which doesn't start with a dash. If it's the first one you've seen, copy that argv value into your search string. If it's the second one, copy it into the filename to read from.

    An easy way to keep track of what you've read is to initialize keyword and filename to something invalid. For example, make keyword[0] = 0. Then in your loop check it to see if it's still that invalid value. If so, you know you haven't seen a keyword yet so the argument you're processing must be it. Then next time through you'll do the check again, see that keyword is set to a non-empty string and you'll know to set the filename to the current argument.

    You can also add error checking - if both keyword and filename are set and you read another non-dash argument, you know that something is wrong.

    But as others have mentioned, if this is a real program use getopt.

    Anyway, to pass a 2-d array.

    Code:
    void print_args(int argc, const char **argv)
    {
       for (i = 0; i < argc; i++)
          printf ("%s\n", argv[i]);
    }
    
    int main(int argc, char *argv[])
    {
       print_args(argc, argv);
       return 0;
    }
    No need to pass it by reference since you're not going to modify it.

    You'll want something like this to extract arguments :

    Code:
    void parse_args(int argc, const char **argv, const char **filename)
    {
       for (i = 0; i < argc; i++)
          printf ("%s\n", argv[i]);
    
       *filename = argv[2]; /* replace with a real search in your application */
    }
    
    int main(int argc, char *argv[])
    {
       const char *filename;
       parse_args(argc, argv, &filename);
    
       FILE *fp = fopen(filename, "r");
    
       return 0;
    }
    Last edited by KCfromNC; 10-19-2010 at 11:04 AM.

  6. #6
    Registered User
    Join Date
    Oct 2010
    Posts
    8
    First of all, KCfromNC, with your help i have fixed some of my biggest errors and I thank you.

    I went back to my other sets of code that I attempted to divvy up main into multiple functions and I have found that I still don't understand prototypes and passing 1-D and 2-D arrays.

    Here is the collection:
    http://pastebin.com/czjRZLfC

    My compile error
    Code:
    "main.c", line 68: warning: argument #2 is incompatible with prototype:
            prototype: pointer to pointer to const char : "newgrep.h", line 16
            argument : pointer to pointer to char
    "main.c", line 68: warning: argument #5 is incompatible with prototype:
            prototype: pointer to pointer to pointer to char : "newgrep.h", line 16
            argument : pointer to array[50] of array[81] of char
    "main.c", line 71: warning: argument #2 is incompatible with prototype:
            prototype: pointer to pointer to const char : "newgrep.h", line 17
            argument : pointer to array[81] of char
    "main.c", line 71: warning: argument #3 is incompatible with prototype:
            prototype: pointer to pointer to const char : "newgrep.h", line 17
            argument : pointer to array[81] of char
    Last edited by Daerogami; 10-19-2010 at 02:23 PM.

  7. #7
    Registered User
    Join Date
    Oct 2010
    Posts
    8
    i think i see what i did, the prototype should mirror the function call, not the variables in the function that were passed from main. Right?

  8. #8
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    The main thing to keep in mind - if you're not changing a variable there's no need to pass it by reference. So in freadIn, you should be passing filename as a char * value since you're just using the value and not modifying it.

    But you could pass it in as a pointer to a pointer, in which case you'd need to dereference it every time you want to use it as a char * value :
    Code:
    fp = fopen(*filename, "r");
    filename in that case is a char **, so dereferencing it once makes it a char * which is what fopen() and other functions expect. You don't need to do this, but it's an example of how to make it work if you had to in some other case.

    Note that even if you modify the contents of filename it's still safe to pass it in as a char *. For example, this works fine.

    Code:
    void fn(char *f)
    {
       f[0] = 'A';
       f[1] = '\n';
       f[2] = '\0';
    }
    
    int main(void)
    {
       char foo[3];
       fn(f);
       puts(f);
       return 0;
    }
    If you think about what's going on, you're not modifying f at all. It still points to the same location throughout the function call. You're just changing what's in the location being pointed to. Since you're not changing the variable in the function, you can pass it by value with no problems.

    2-D arrays are a bit more complicated. Here's a good reference Arrays and Pointers. Unfortunately, this makes life tough. What you want to do is something like this for your prototype :

    void freadIn( char *filename, const char **argv, int argc, int lines, char str[][81]);

    Since str in your main is allocated as char str[X][Y], it just grabs a block of memory X*Y bytes long. When you pass that into the function, the function has to know know big Y is so it can know where str[0], str[1] and so on start within that block.

    You'd call the function by just passing in str. Not *str, not &str, just str. This works just like my example above. str points to the same location throughout the whole function, you're just changing values in the memory pointed to by str. Since str itself never changes, no need to add another layer of dereferencing.

    You'll need to make similar changes to the other function. Start with just the freadIn and get that going first - comment out the other function and the stuff after you call it and focus on getting that working. Maybe put a dummy loop to print out the file you read.

    Note that working means compiling without errors or warnings and running correctly.

    Which brings me to my next point - how are you going to know how many lines you've read? It's a parameter to freadIn and being modified in there. But since it's passed by value none of the changes in that function get passed back to main. And it's never used again anyway - which means that it should either be a local variable in freadIn or it needs to be passed by value and passed in to other functions which use it. Or you could just make it the return value of the function and error out if you read 0 lines.

    But all of this complexity points to a different question : would it be easier to process the file line by line instead of reading the entire file in at once? It would remove a lot of the complexity of having to deal with 2-D arrays. It also means the program will work with abritrary-sized files instead of blowing up if you run into one with more that 50 lines.

    Other notes :

    In the check for the next arg after -o to be there, you should be looking at argc compared to i. I wouldn't count on argv[][] being valid past the count identified in argc. Also, think about the error message a bit - why bother printing the name if you know it's NULL?
    And on that same line, argv[i][0] is a char, not a char * but you're treating it as one by comparing it to NULL and printing it as a string. Here's a good example of where warnings would tell you something's wrong.
    Be careful with the const qualifier - for instance you're calling strOut a const char ** in ftokPro but then writing into it. This will go away when you apply the fix to change it to char [][81], but keep it in mind in general. Same with str in the same function.
    The return at the end of a void function isn't needed. But if you put it in, don't put the empty parens on it.

  9. #9
    Registered User
    Join Date
    Oct 2010
    Posts
    8
    Quote Originally Posted by KCfromNC View Post
    But all of this complexity points to a different question : would it be easier to process the file line by line instead of reading the entire file in at once? It would remove a lot of the complexity of having to deal with 2-D arrays. It also means the program will work with abritrary-sized files instead of blowing up if you run into one with more that 50 lines.
    I found out this today in class, im scrapping pretty much everything after my switch statement and starting from there after tweaking it a bit. I intend on going over your post till I understand what I was doing and avoid making a messy situation of arrays and pointers.

    Once again, thank you!

  10. #10
    Registered User
    Join Date
    Oct 2010
    Posts
    8
    KCfromNC, I can now say I better understand double pointers and exactly where my pitfalls were.

    Now that I have rewritten a bit of my program I am getting the infamous segmentation fault.
    I have debugged, read, debugged, read, tinkered, debugged some more and cannot trace down my error.
    I have noted where my segmentation fault is believed to occur.

    Main and Header = http://pastebin.com/SS7MizjY
    Code:
    /*
      This function searches a string for a matching keyword passed
      into it.
      reads in: str, *str, *int, *int, int, int
    */
    
    #include "newgrep.h"
    
    char * searchBuffer( char *keyword, char * buffer, int * lines,
                         int * occur, int boolI){
    
      char *lineOut,  // Line containing keyword
           *token;    // Character ptr for strtok
    
      int  i = 0,         // Loop variables independent of main
           boolLine = 0;  // Boolean to bypass multiple "occur" counts
    
      // Give lineOut somewhere to be in the the size of buffer
      lineOut = (char*) malloc(sizeof(buffer));
      // Copy buffer to lineOut before it is modified by strtok
      strcpy(lineOut, buffer);
      
      // Upper-case buffer for -o option
      if( boolI == 1 ){
        for( i = 0; i < strlen(buffer); i++){
            buffer[i]=toupper(buffer[i]);
        }
        for( i = 0; i < strlen(keyword); i++)
          keyword[i]=toupper(keyword[i]);
      }
    
      i = 0; // re-initialize i
      token = strtok(buffer, " ,.-\n"); // priming token
    printf("Token is %s\n", token);
    getchar();
    fflush(stdin);
      while(token != NULL){
        if( strncmp(token, keyword, strlen(keyword)) == 0){
          *occur ++; // Count match
          boolLine = 1;
        }
        // ERROR OCCURS HERE AFTER 3rd iteration when buffer is at end!
        token = strtok(NULL, " ,.-\n"); // continue tokenizing
    printf("Token is %s\n", token);
    getchar();
    fflush(stdin);
      }
    printf("NOT LOOPING ANYMORE!");
    getchar();
    fflush(stdin);
      if( boolLine == 1 ){
        *lines ++; 
      }else{
        for(i=0; i<strlen(lineOut); i++){
          lineOut[i] = '\0';
        }
      }
    printf("line Out contains <%s>\n", lineOut);
      
      return(lineOut);
    }
    Here is my console output
    Code:
    > newgrep -i is file.dat
    
    There were 4 arguments passed to args.
    
    Token is THIS
    
    Token is IS
    
    Token is A
    
    Token is FILE
    
    Segmentation fault
    for this output,

    buffer = "This is a file";
    keyword = "is";
    Last edited by Daerogami; 10-24-2010 at 07:31 PM.

  11. #11
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This needs a make-over, imo.:

    Code:
    fflush(stdin);
      while(token != NULL){
        if( strncmp(token, keyword, strlen(keyword)) == 0){
          *occur ++; // Count match
          boolLine = 1;
        }
        // ERROR OCCURS HERE AFTER 3rd iteration when buffer is at end!
        token = strtok(NULL, " ,.-\n"); // continue tokenizing
    printf("Token is %s\n", token);
    getchar();
    fflush(stdin);
      }
    1) don't fflush(stdin) - you're trying to flush the kitchen faucet, instead of the toilet!

    2) token = strtok() needs to be on the last line of the loop, because it may be NULL, and you need to test it BEFORE you do something with it - like trying to print it out!

    That's what's causing your seg fault.

    You REALLY need to get your indentation down, to see what's going on with your logic. You'll catch a lot of errors very easily if you just indent properly.

    Yes, this indentation is horrible.

  12. #12
    Registered User
    Join Date
    Oct 2010
    Posts
    8
    i forgot to mention, when my indentation is against the edge it's debug code so i can look down the side and see what to delete.
    and the fflush(); is to clear getchar(); another part of debugging, it does it with and with out it

    edit: all that aside, i was so involved in debugging i found out my issue without realizing it and you showed that to me in the code you quoted and explained.
    I guess spending double digit hours of coding tend to throw your head in the dirt
    I keep telling myself, "One day I'll understand what im doing AND what im trying to do."
    Last edited by Daerogami; 10-24-2010 at 11:49 PM.

  13. #13
    Registered User
    Join Date
    Oct 2010
    Posts
    8
    DONE! It works. Thank you Adak and KCfromNC for all your help!
    Here is a script recording of the files displayed with cat and basic output at the bottom
    Code:
    Script started on Mon Oct 25 18:18:43 2010
    %cat newgrep.h
    
    
    /*********************************************************************
    
      Name: Mark Clark
    
      Assignment: Lab 4
    
      Last Revision: 10/7/10
    
      Desc: This program searches a file for occurences of a string. This
    
      program is somewhat similar to the Unix grep utility, thus is called
    
      newgrep.
    
    *********************************************************************/
    
    
    
    #include <stdio.h>
    
    #include <string.h>
    
    #include <stdlib.h>
    
    #include <math.h>
    
    #include <ctype.h>
    
    
    
    char * searchBuffer( char *, char * , int * , int *, int);
    
    %cat searchBuffer.c
    
    
    /*
    
      This function searches a string for a matching keyword passed
    
      into it.
    
      reads in: str, *str, *int, *int, int, int
    
    */
    
    
    
    #include "newgrep.h"
    
    
    
    char * searchBuffer( char *keyword, char * buffer, int * lines,
    
                         int * occur, int boolI){
    
    
    
      char *lineOut,                // Line containing keyword
    
           *token = NULL,           // Character ptr for strtok
    
           lineOutNull[1] = {'\0'}; // Empty array for passing back
    
    
    
      int  i = 0,         // Loop variables independent of main
    
           boolLine = 0;  // Boolean to bypass multiple "occur" counts
    
    
    
      // Revision: Mem Alloc Unneccesary
    
      lineOut = (char *) calloc( strlen(buffer), sizeof(buffer) );
    
      if(lineOut == NULL){
    
        fprintf(stderr, "MEMORY ALLOCATION FAILURE!\n");
    
        exit(1);
    
      }
    
    
    
      // Copy buffer to lineOut before it is modified by strtok
    
      strcpy(lineOut, buffer);
    
      for( i = 0; i < strlen(lineOut); i++){ // uppercase lineOut
    
        if( lineOut[i] != '\0')
    
          lineOut[i]=(char)toupper(lineOut[i]);
    
      }
    
    
    
      // Upper-case buffer for -o option
    
      if( boolI == 1 ){
    
        for( i = 0; i < strlen(buffer); i++){
    
          if( buffer[i] != '\0')
    
            buffer[i]=(char)toupper(buffer[i]);
    
        }
    
        for( i = 0; i < strlen(keyword); i++)
    
          if( keyword[i] != '\0')
    
            keyword[i]=(char)toupper(keyword[i]);
    
      }
    
    
    
      i = 0; // re-initialize i
    
      token = strtok(buffer, " ,.-\n"); // priming token
    
      while(token != NULL){
    
        if( strncmp(token, keyword, strlen(keyword)) == 0){
    
          *occur = *occur + 1; // Count matches
    
          boolLine = 1;
    
        }
    
        token = strtok(NULL, " ,.-\n"); // continue tokenizing
    
      }
    
      
    
      if( boolLine == 1 ){
    
        *lines = *lines + 1;
    
      }else{
    
        return(lineOutNull);
    
      }  
    
      return(lineOut);
    
    }
    
    %cat main.c
    
    
    /**********************
    
      Depends on newgrep.h
    
     **********************/
    
    
    
    #include "newgrep.h"
    
    
    
    int main ( int argc, char * argv[] ){
    
    
    
      char  outFile [81],   // Output file
    
            keyword [81],   // Word for string compare
    
            filename [81],  // File argument in argv(a.k.a. file)
    
            **lineOut,      // Output from token loop
    
            *buffer,        // Line for searching
    
            option;         // Option for switch statement
    
    
    
      int   i = 0, // Loop Counter
    
            j = 0, // Argument String elements
    
            k = 0, // Secondary Loop Counter
    
            l = 0, // lineOut element counter for searchBuffer return
    
            lines = 0,  // how many lines occur is counted in
    
            occur = 0,  // how many times keyword occurs
    
            boolI = 0,  // Boolean value for option I
    
            boolO = 0;  // Boolean value for option O
    
            
    
      FILE * fp,  // File Pointer for input file (3rd arg)
    
           * ofp; // File pointer for output file
    
    
    
      //Set both character arrays to zero for option check
    
      filename[0] = 0;
    
      keyword[0] = 0;
    
    
    
      // Echo number of arguments passed into main
    
      if( argc < 3 ){
    
        fprintf (stderr, "\nInsufficient arguments!\n\n" );
    
        exit(1);
    
      }else{
    
        printf ( "\nThere were %d arguments passed to args.\n\n", argc);
    
      }
    
      
    
      // Finds Option elements, loops skips first argument(program name)
    
      for( i = 1 ; i < argc ; i++){  // Loop thru arguments, re-init i
    
        if ( argv[i][0] == '-' ){    // Look for '-' as first character
    
          j =  strlen(argv[i]);      // Set j for max loop cycles
    
          for( k = 0 ; k < j ; k++){ // loop cycles element i's char array 
    
            option = argv[i][k];     // set current char to option
    
            switch( option ){        // test for either 'i'|'I' or 'o'|'O'
    
    
    
              case 'i':
    
              case 'I':
    
                boolI = 1;
    
                break;
    
    
    
              case 'o':
    
              case 'O':
    
                boolO = 1;
    
                if( argv[i+1][0] != NULL ){
    
                  strcpy(outFile, argv[i+1]);
    
                }else{
    
                  fprintf ( stderr, "Invalid File Argument <%s>!\n",
    
                  argv[i+1][0]);
    
                  exit(1);
    
                }
    
                break;
    
    
    
              default:
    
                break;
    
            }
    
          }
    
        }else if( keyword[0] == 0 ){
    
          strcpy(keyword, argv[i]);
    
        }else if( filename[0] == 0 ){
    
          strcpy(filename, argv[i]);
    
        }
    
      }
    
    
    
      // #########################
    
      // #### File Operations ####
    
      // #########################
    
    
    
      // Check to see if file is valid
    
      if ( (fp=fopen (filename, "r") ) == NULL){
    
          fprintf ( stderr, "File IO: Unable to open \"%s\"!\n",
    
          filename);
    
          exit(1);
    
        }
    
      // Allocate memory to buffer then read in until newline
    
      buffer = (char*) malloc(256);
    
      while ( fgets(buffer, 255, fp) != NULL ){
    
        if( buffer[strlen(buffer) - 1] == '\n' )
    
          buffer[strlen(buffer) - 1] = '\0';  // Replace new line at end
    
    
    
          //lineOut is a 2-D array main, searchBuffer's lineOut is 1-D
    
        lineOut[l] = searchBuffer( keyword, buffer, &lines, &occur, boolI);
    
        l++;  // move to next element of main's 2-D "lineOut"
    
      }
    
    
    
      // ################
    
      // #### Output ####
    
      // ################
    
      if(boolO == 1){  // Check if -o Option is true
    
        ofp = fopen(outFile, "w");  // Open file passed in from kernel
    
        if (ofp != NULL){
    
          fprintf(ofp, "\n"); // Initialize file with newline
    
          for(i=0; i < l ; i++){
    
            if(lineOut[i][0] != '\0') // Check if lineOut contains anything
    
              fprintf(ofp, "Keyword found in line[%d]: %s\n", i+1,
    
                      lineOut[i] );
    
          }
    
          fprintf(ofp, "\n\"%s\" occurs %d times in %d lines.\n",
    
                  keyword, occur, lines);
    
          fclose (ofp);
    
          printf("Successful Write to %s\n", outFile);
    
        }
    
      // Prints to stdout
    
      }else{
    
        for(i=0; i < l; i++){
    
          if(lineOut[i][0] != '\0') // Check if lineOut contains anything
    
            printf("Keyword found in line[%d]: %s\n", i+1, lineOut[i] );
    
        }
    
        printf("\n\"%s\" occurs %d times in %d lines.\n",
    
               keyword, occur, lines);
    
      }
    
      return(0);
    
    }
    
    %newgrep is file.dat
    
    
    
    
    There were 3 arguments passed to args.
    
    
    
    Keyword found in line[1]: THIS IS A FILE
    
    
    
    "is" occurs 1 times in 1 lines.
    
    %exit
    
    
    exit
    
    
    script done on Mon Oct 25 18:19:20 2010

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 02-02-2009, 07:27 AM
  2. Help with reading strings and opening files PLEASE
    By green2black in forum C Programming
    Replies: 8
    Last Post: 11-17-2008, 05:46 PM
  3. Pass Filename to another function
    By awesmesk8er in forum C Programming
    Replies: 9
    Last Post: 10-24-2008, 01:43 PM
  4. Reading Filename
    By C_ntua in forum C# Programming
    Replies: 6
    Last Post: 10-13-2008, 09:28 AM
  5. Replies: 2
    Last Post: 01-28-2008, 03:07 AM