diff --git a/k&r/04-funcs-and-prog-struct/04-find/04-find-no-overflow.c b/k&r/04-funcs-and-prog-struct/04-find/04-find-no-overflow.c index 138d009..e3396cc 100644 --- a/k&r/04-funcs-and-prog-struct/04-find/04-find-no-overflow.c +++ b/k&r/04-funcs-and-prog-struct/04-find/04-find-no-overflow.c @@ -7,25 +7,44 @@ void println(void); int flush_lnbuff(void); int getch_lnbuff(void); + /* find: prints lines containing pattern, returns number of matching lines * gracefully handle line overflow */ -int find(char *pattern) +int find(char *pattern, char lineno_flag, char except_flag) { int found, i, c; const int plen = strlen(pattern); - + long lineno = 1; i = found = 0; + char match = 0; - while ((c = getch_lnbuff()) != EOF) +#define print_lineno() if (lineno_flag) printf("%ld:", lineno) + while ((c = getch_lnbuff()) != EOF) { + if (c == '\n') { /* newline */ + if (except_flag && !match) { + print_lineno(); + flush_lnbuff(); + putchar('\n'); + } + match = 0; + lineno++; + } if (c != pattern[i]) i = 0; else if (++i == plen) { // found match + if (except_flag) { + match = 1; + continue; + } i = 0; found++; + print_lineno(); flush_lnbuff(); - println(); + println(), lineno++; } + } return found; +#undef print_lineno } /* println: prints next line from stdin @@ -49,7 +68,8 @@ static_assert(!(LNBUFF_LEN % 2), "Line buffer length is not a power of two!"); struct { char self[LNBUFF_LEN]; unsigned len; -} lnbuff = {.len= 0}; + char newline; +} lnbuff = {.len=0, .newline=1}; /* LNBUFF_I: current index in line buffer */ #define LNBUFF_I (lnbuff.len & (LNBUFF_LEN - 1)) @@ -58,9 +78,13 @@ struct { int getch_lnbuff() { int c = getchar(); - - if (c == EOF || c == '\n') // new line + + if (lnbuff.newline) { lnbuff.len = 0; + lnbuff.newline = 0; + } + if (c == EOF || c == '\n') // new line + lnbuff.newline = 1; else { lnbuff.self[LNBUFF_I] = c; lnbuff.len++; @@ -89,3 +113,4 @@ int flush_lnbuff() lnbuff.len = 0; return i; } + diff --git a/k&r/04-funcs-and-prog-struct/04-find/04-find-opt.c b/k&r/04-funcs-and-prog-struct/04-find/04-find-opt.c index 8ebebd4..047dae4 100644 --- a/k&r/04-funcs-and-prog-struct/04-find/04-find-opt.c +++ b/k&r/04-funcs-and-prog-struct/04-find/04-find-opt.c @@ -7,14 +7,17 @@ int getln(char line[], int lim); int strindex(char source[], char searchfor[], int slen); /* find: prints lines containing pattern, returns number of matching lines */ -int find(char *pattern) +int find(char *pattern, char lineno_flag, char except_flag) { char line[MAXLINE]; int found = 0; int slen = strlen(pattern); + long lineno; - while (getln(line, MAXLINE) > 0) - if (strindex(line, pattern, slen) >= 0) { + for (lineno = 1; getln(line, MAXLINE) > 0; lineno++) + if ((strindex(line, pattern, slen) >= 0) != except_flag) { + if (lineno_flag) + printf("%ld:", lineno); printf("%s", line); found++; } diff --git a/k&r/04-funcs-and-prog-struct/04-find/04-find.c b/k&r/04-funcs-and-prog-struct/04-find/04-find.c index 276d28b..6b9d993 100644 --- a/k&r/04-funcs-and-prog-struct/04-find/04-find.c +++ b/k&r/04-funcs-and-prog-struct/04-find/04-find.c @@ -3,7 +3,7 @@ /* compile with 04-find-no-overflow.c or 04-find-opt.c * gcc 04-find.c [04-find-no-overflow.c | 04-find-opt.c] */ -int find(char *pattern); +int find(char *pattern, char lineno_flag, char except_flag); #define ARG_FLAGS X('n', lineno) X('x', except) @@ -17,7 +17,7 @@ int main(int argc, char *argv[]) char c; /* declare flag variables */ -#define X(c, flag_var) int flag_var = 0; +#define X(c, flag) char flag##_flag = 0; ARG_FLAGS #undef X char **parg = argv; @@ -29,7 +29,7 @@ int main(int argc, char *argv[]) } while (c = *++parg[0]) switch (c) { - #define X(C, flag_var) case C: flag_var = 1; break; + #define X(C, flag) case C: flag##_flag = 1; break; ARG_FLAGS #undef X default: @@ -40,6 +40,7 @@ int main(int argc, char *argv[]) --argc; } + /* illegal arguments */ if (argc != 2) { printf("usage: find "); #define X(c, _) printf("[-%c] ", c); @@ -57,6 +58,6 @@ int main(int argc, char *argv[]) return -2; } - int found = find(pattern); + int found = find(pattern, lineno_flag, except_flag); return found; }