Previous: 11.2.4 String Conversion Functions
Up: 11.2 Library String Functions
Previous Page: 11.2.4 String Conversion Functions
Next Page: 11.3 More Example Programs

11.2.5 File I/O with Strings

Earlier in this chapter, we described library functions to do string I/O with the standard input and output. The library also provides functions to do I/O with files. Here we will illustrate the use of these functions with our next task; to search for the presence of a string in the lines of a text file.

GETLNS: Search for a control string in the lines of a file. Each line that contains the control string is to be written to an output file and to the standard output.

The algorithm is written easily if we write a function, srchstr(), that searches for the presence of one string in another. Here is the algorithm:

get the control string control
    open files

while not EOF, read a line s from the input file if srchstr(s, control) is True then write the line to output file and stdout

We could use character I/O to read from an input file, but it is easier to use library string I/O functions: fgets() and fputs().

int fgets(STRING s, int n, FILE *fp);
    int fputs(STRING s, FILE *fp);

These functions are similar to gets() and puts() with minor differences. The function fgets() reads a string from a stream, fp, into a buffer, s. The maximum size, n, of the string buffer must be specified to fgets() and must allow for a terminating NULL character. The function reads a string until a newline character is encountered or the specified maximum size of buffer is reached. It adds the terminating NULL, but it does NOT strip the newline character as does gets(). The NULL is added after the n character and fgets() returns the buffer pointer if successful, or NULL otherwise.

The function fputs() outputs a string to a stream fp. It strips the terminating NULL from the string, but does NOT add a newline character as does puts(). The function returns the last character output if successful, EOF otherwise. The prototypes for these functions are included in stdio.h.

The program driver for our task is easy to write as shown in Figure 11.8. The program driver first reads the control string to search for. It then opens the input and output files. The while loop reads lines from the input file until end of file. Each line read is tested by srchstr() for the presence of the control string. If the control string is present in the line, it is written to both stdout and the output file. We will need TRUE and FALSE definitions for srchstr(), so we have included the header file, tfdef.h.

The function, srchstr() traverses the string, s, and tests if the control string is present at each position in s. If it is present, it returns TRUE; otherwise, it goes to the next position. The function, srchstr(), uses a function, compare(), to see if a string is present at the start of another string. This is different than strcmp() since the string we are searching in may not terminate at the end of the control string.

The code for srchstr() is shown in Figure 11.9. Given a string, s, and a control string, str, it starts at the first character of s, and calls compare() to see if str is present in s starting at the first character. If it is, it returns TRUE; otherwise, it increments s to point to the next character. If the string is exhausted, it returns FALSE.

The code for compare() is shown in Figure 11.10. It traverses str and s until str is exhausted. If it encounters corresponding characters that are not the same in the two strings, it returns FALSE. When str is exhausted, it returns TRUE. Here is a sample session:

The file ucstr.c contains only one line with the string while in it. That line is written to the file xyz and to stdout.

For this task, we have written our own function to compare str with the first several characters in string s because we do not expect s to terminate at the end of the control string, str. If n is the length of str, then we require a comparison of the first n characters in the two strings. There is a standard library function, strncmp(), which does just that:

int strncmp(STRING s, STRING t, unsigned n);
It compares the first n characters of s and t, and returns the difference of the first unequal characters, or it returns zero if they are all equal, just like strcmp(). So, instead of compare(s, str), we could have used:
strncmp(s, str, strlen(str))
A similar library function, strncpy(), is also available:
STRING  strncpy(STRING s, STRING t, unsigned n);
which copies n characters from the source string, t, into the destination string, s, without adding a terminating NULL. It returns s.

We close this section by emphasizing the difference between gets(s) and fgets(s, n, fp). Let us assume an input string "Hawaiin" is in the standard input, and that the string s is large enough to accommodate the example string with n selected appropriately. The string, s is shown below after the use of each function:

gets(s):               Hawaii\0     /* newline stripped, NULL appended */
   fgets(s, n, stdin):    Hawaii\n\0   /* newline present, NULL appended */

Similarly, the output of the functions puts(s) and fputs(s, fp) is shown below:

puts(s):               Hawaii\n  /* NULL stripped, newline appended */
   fputs(s, stdout):      Hawaii\n  /* NULL stripped */



Previous: 11.2.4 String Conversion Functions
Up: 11.2 Library String Functions
Previous Page: 11.2.4 String Conversion Functions
Next Page: 11.3 More Example Programs

tep@wiliki.eng.hawaii.edu
Sat Sep 3 07:04:57 HST 1994