diff --git a/mygrep/README.md b/mygrep/README.md index 78ecd1c..0a68f8d 100644 --- a/mygrep/README.md +++ b/mygrep/README.md @@ -10,7 +10,7 @@ The program `mygrep` reads files line by line and for each line checks whether i term keyword. The line is printed if it contains the keyword, otherwise it is not printed. The program accepts lines of any length. -If one or multiple input files are specified (given as positional arguments after keyword), then mygrep +If one or multiple input files are specified (given as positional arguments after keyword), then mygrep reads each of them in the order they are given. If no input file is specified, the program reads from `stdin`. diff --git a/mygrep/mygrep.c b/mygrep/mygrep.c index 672fa7d..64b5788 100644 --- a/mygrep/mygrep.c +++ b/mygrep/mygrep.c @@ -1,6 +1,8 @@ +#define _GNU_SOURCE // in order for strcasestr to work #include #include #include +#include #include "mygrep.h" void main(int argc, char *argv[]) { @@ -12,6 +14,7 @@ void main(int argc, char *argv[]) { char *filename = NULL; int c; + // Get the options while((c = getopt(argc, argv, "io:h")) != -1) { switch(c) { case 'i': @@ -21,7 +24,9 @@ void main(int argc, char *argv[]) { ofile = optarg; break; case 'h': + printf("Command usage:\n"); print_usage(); + exit(EXIT_SUCCESS); break; case '?': print_usage(); @@ -31,6 +36,7 @@ void main(int argc, char *argv[]) { } } + // Check if the required argument is there if(argv[optind] == NULL) { printf("Mandatory argument 'keyword' missing.\n"); print_usage(); @@ -40,8 +46,31 @@ void main(int argc, char *argv[]) { filename = argv[optind + 1]; } - if(filename == NULL) { - check_for_string("test", keyword); + // Get user input if there is no input file defined + while(filename == NULL) { + size_t len; // Define an unsigned string length value + + if(getline(&filename, &len, stdin)) { // Read until new line + check_for_string(filename, keyword, iflag, ofile); + filename = NULL; // Reset the input + } + } + + // Get data from input file + if(filename != NULL) { + FILE *in; + if((in = fopen(filename, "r")) == NULL) { + printf("Error opening the file %s\n", filename); + exit(EXIT_FAILURE); + } + + size_t len; + char *line = NULL; // Define a pointer to hold our value + + // Read the file line by line and execute check_for_string for each line + while(getline(&line, &len, in) != -1) { + check_for_string(line, keyword, iflag, ofile); + } } exit(EXIT_SUCCESS); @@ -51,6 +80,7 @@ void print_usage() { printf("mygrep [-i] [-o outfile] keyword [file...]\n"); } +// Check for coorect number of options void check_opts_number(int argc, char *argv[]) { if(argc <= 1) { fprintf(stderr, "At least one argument expected.\n"); @@ -63,6 +93,32 @@ void check_opts_number(int argc, char *argv[]) { } } -void check_for_string(char *to_check, char *to_find) { - printf("Not implemented. This function will search for the substring %s in the string %s.\n", to_find, to_check); +void check_for_string(char *to_check, char *to_find, int iflag, char *ofile) { + if(ofile == NULL) { + /** + * Find the first occurance of needle in haystack and return it as a pointer. + * If found, print haystack + **/ + if(iflag == 0 && strstr(to_check, to_find) != NULL) printf("%s", to_check); + else if(iflag == 1 && strcasestr(to_check, to_find)) printf("%s", to_check); + } else { + /** + * Open the specified file for appending + * Find the first occurance of needle in haystack and return it as a pointer. + * If found, append haystack to the end of the file + * Close the file + **/ + FILE *out; + + // Check if the file was opened successfully + if((out = fopen(ofile, "a")) == NULL) { + printf("Error opening the file %s\n", ofile); + exit(EXIT_FAILURE); + } + + if(iflag == 0 && strstr(to_check, to_find)) fprintf(out, "%s", to_check); + else if(iflag == 1 && strcasestr(to_check, to_find)) fprintf(out, "%s", to_check); + + fclose(out); + } } diff --git a/mygrep/mygrep.h b/mygrep/mygrep.h index cbdbe92..d522ad3 100644 --- a/mygrep/mygrep.h +++ b/mygrep/mygrep.h @@ -3,6 +3,6 @@ void print_usage(); void check_opts_number(int argc, char *argv[]); -void check_for_string(char *to_check, char *to_find); +void check_for_string(char *to_check, char *to_find, int iflag, char *ofile); #endif \ No newline at end of file