Exercise 13-20 and 13-21 - CBD page 467-468

Solution index                   Textual C program


/* Exercise 13-20 and 13-21, CBD, page 467-468. Programmed by Kurt Normark aided 
   heavily by the hints of the text book */

#include <stdio.h>
#include <string.h>

#define MAXLINE 200

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

  char line[MAXLINE], *pattern, *file_name;
  FILE *ifp;
  int line_numbers, n = 1;

  if (argc == 3) {
    file_name = argv[2]; line_numbers = 0; pattern = argv[1];
  }
  else if (argc == 4 && strcmp(argv[1], "-n") == 0) {
    file_name = argv[3]; line_numbers = 1; pattern = argv[2];
  }
  else {
    fprintf(stderr, "Calling form: search [-n] search_string file\n");
    exit(1);
  }
  
  if ((ifp = fopen(file_name, "r")) == NULL){
    fprintf(stderr, "\nCannot open %s\n\n", file_name);
    exit(1);
  }

  while(fgets(line, MAXLINE, ifp) != NULL){
    if (strstr(line, pattern) != NULL){
      if (line_numbers)
        printf("%3i: %s", n, line);
      else
        printf("%s", line);
    }
    n++;
  }

  fclose(ifp);
  
  return 0;
}

In this exercise we write a program which prints lines of a file that contain a given search string. The solution is aided by the hint of the text book, given on the top of page 468. As a consequence of this, and somewhat unusual, the entire program is made in the main function. The solution includes the -n option, as asked for in exercise 13-21.

The program can be called as
  search printf search.c
or as
  search -n printf search.c
where we in both cases search for 'printf' in the source program itself.
 

if (argc == 3) {
  file_name = argv[2]; line_numbers = 0; pattern = argv[1];
}
else if (argc == 4 && strcmp(argv[1], "-n") == 0) {
  file_name = argv[3]; line_numbers = 1; pattern = argv[2];
}
else {
  fprintf(stderr, "Calling form: search [-n] search_string file\n");
  exit(1);
}

if ((ifp = fopen(file_name, "r")) == NULL){
  fprintf(stderr, "\nCannot open %s\n\n", file_name);
  exit(1);
}
There is a certain amount of error handling and initialization work in the program. If there are three parts of argv (the program parameters) they are assumed to be the program name, the search string, and the name of the file in which to search. Similarly, if there are four parts, and if the second is "-n", the third is assumed to be the search string, and the fourth is the name of the file. Notice the initialization of line_numbers (boolean variable), file_name (the file to search in), and pattern (the search string).
 

while(fgets(line, MAXLINE, ifp) != NULL){
  if (strstr(line, pattern) != NULL){
    if (line_numbers)
      printf("%3i: %s", n, line);
    else
      printf("%s", line);
  }
  n++;
}
In the while loop we read one line at a time with the standard library function fgets. Take a careful look at the description of this function on page 541 in CBD. If fgets returns a line, the string.h function strstr looks for a match of pattern somewhere in line. If it succeeds, the line is printed with or without the line number n. Notice that we print on standard output. The variable n is incremented as the final action in the loop. The initial value of n must be 1.
 

fclose(ifp);

return 0;
We close the file, and return 'the success value 0' at the end of main.
 


Generated: Wednesday, April 5, 2006, 15:21:07
This program dissection page is generated from an XML-in-LAML source file