Exercise 7-7 (pattern)
Chapter_7 Exercise_7-6 | Exercise_7-8 |
Exercise 7-7 K&R, p. 165
Exercise 7-7. Modify the pattern_finding_program of Chapter_5 to take its input from a set of named files or, if no files are named as arguments, from the standard input. Should the file name be printed when a matching line is found?
Note: See also cat_(concatenate).
CONTENTS: Khayam.txt pattern.c
Khayam.txt K&R, p. 68 download
Ah Love! could you and I with Fate conspire
To grasp this sorry Scheme of Things entire,
Would not we shatter it to bits -- and then
Re-mould it nearer to the Heart's Desire!
pattern.c K&R, p. 164-165 download
#include <stdio.h> // for fprintf(), putchar(), fopen(), fclose(),
// ferror(), getc(), putc(), stdin, stdout, stderr, FILE, EOF, NULL
#include <string.h> // for strlen(), strstr()
#include <stdlib.h> // for exit()
#define MAXLINE 1000
// get at most n-1 chars from fp:
char * fGets(char *s, int n, FILE *fp); // fgets() is in stdio.h
// read a line, return length:
int getLine(char *line, int max); // getline() is in stdio.h
// write string line on stdout:
int writeLine(char *line);
int main(int argc, char *argv[])
{
char *prog = argv[0]; // initialize
FILE *fp = stdin; // default value
char *pattern = "ould"; // default value
char line[MAXLINE];
int lineno = 0;
if (argc >= 2) {pattern = argv[1];}
if (argc < 3)
{
printf("%s: search for pattern \"%s\" in \"stdin\":\n",
prog, pattern);
while(getLine(line, MAXLINE) > 0)
{
lineno++;
if (strstr(line, pattern) != NULL)
{
printf("%d: ", lineno);
writeLine(line);
}
}
exit(0); // end program normally
}
// here argc >= 3 and pattern == argv[1]
argc -= 2, argv += 2;
for ( ; argc-- > 0; argv++)
{
lineno = 0; // reset
fp = fopen(*argv, "r");
if (fp == NULL)
{
fprintf(stderr, "%s: can't open \"%s\"\n", prog, *argv);
exit(1); // end program, signalling error
}
printf("%s: search for pattern \"%s\" in \"%s\":\n",
prog, pattern, *argv);
while(fGets(line, MAXLINE, fp) != NULL)
{
lineno++;
if (strstr(line, pattern) != NULL)
{
printf("%d: ", lineno);
writeLine(line);
}
}
putchar('\n');
fclose(fp);
}
if (ferror(stdout))
{
fprintf(stderr, "%s: error writing stdout\n", prog);
exit(2); // end program, signal other error code
}
exit(0);
}
// get at most n-1 chars from fp
char * fGets(char *s, int n, FILE *fp) // fgets() is in stdio.h
{
register int c;
register char *cs;
cs = s;
while (--n > 0 && (c = getc(fp)) != EOF)
{
if ((*cs++ = c) == '\n')
{break;}
}
*cs = '\0';
return (c == EOF && cs == s) ? NULL : s;
}
// read a line, return length:
int getLine(char *line, int max) // getline() is in stdio.h
{
if (fGets(line, max, stdin) == NULL)
{return 0;}
// else
return strlen(line); // sizeof(line)
}
// put string s on file fp:
int fPuts(char *s, FILE *fp) // fputs() is in stdio.h
{
int c;
while (c = *s++)
{putc(c, fp);}
return ferror(fp) ? EOF : 0;
}
int writeLine(char *line)
{
return fPuts(line, stdout);
}
/*
gcc pattern.c -o pattern
./pattern ink
./pattern: search for pattern "ink" in "stdin":
I think therefore I am
1: I think therefore I am
I am therefore I think
2: I am therefore I think
I like rain
The rain in Spain stays mainly in the plain
Ink is a dye
Brink! is about skating
6: Brink! is about skating
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
./pattern < Khayam.txt
./pattern: search for pattern "ould" in "stdin":
1: Ah Love! could you and I with Fate conspire
3: Would not we shatter it to bits -- and then
4: Re-mould it nearer to the Heart's Desire!
./pattern ear < Khayam.txt
./pattern: search for pattern "ear" in "stdin":
4: Re-mould it nearer to the Heart's Desire!
./pattern cat cat1.c cat2.c
./pattern: search for pattern "cat" in "cat1.c":
6: // concatenate files, version 1
23: printf("cat1: can't open \"%s\"\n", *argv);
42: gcc cat1.c -o cat1
43: ./cat1
52: ./cat1 cat1.c
54: ./cat1 cat1.c cat1.c
./pattern: search for pattern "cat" in "cat2.c":
7: // concatenate files, version 2
48: gcc cat2.c -o cat2
49: ./cat2
56: ./cat2 cat2.c
58: ./cat2 cat1.c cat2.c
*/
Chapter_7 Exercise_7-6 | BACK_TO_TOP | Exercise_7-8 |
Comments
Post a Comment