TCPL/7.7_Line_Input_and_Output

7.7 Line Input and Output 行输入和行输出

The standard library provides an input and output routine fgets that is similar to the getline function that we have used in earlier chapters:

   char *fgets(char *line, int maxline, FILE *fp)

fgets reads the next input line (including the newline) from file fp into the character array line; at most maxline-1 characters will be read. The resulting line is terminated with '\0'. Normally fgets returns line; on end of file or error it returns NULL. (Our getline returns the line length, which is a more useful value; zero means end of file.)

标准库提供了一个输入函数fgets,它和前面几章中用到的函数getline类似。

   char *fgets(char *line, int maxline, FILE *fp)

fgets函数从fp指向的文件中读取下一个输入行(包括换行符),并将它存放在字符数组line中,它最多可读取maxline-1个字符。读取的行将以'\0'结尾保存到数组中。通常情况下,fgets返回line,但如果遇到了文件结尾或发生了错误,则返回NULL(我们编写的getllne函数返回行的长度,这个值更有用,当它为0时意味着已经到达了文件的结尾)。

For output, the function fputs writes a string (which need not contain a newline) to a file:

   int fputs(char *line, FILE *fp)

It returns EOF if an error occurs, and non-negative otherwise.

输出函数fputs将一个字符串(不需要包含换行符)写入到一个文件中

   int fputs(char *line, FILE *fp)

如果发生错误,该函数将返回EOF,否则返回一个非负值。

The library functions gets and puts are similar to fgets and fputs, but operate on stdin and stdout. Confusingly, gets deletes the terminating '\n', and puts adds it.

库函数gets和puts的功能与fgets和fputs函数类似,但它们是对stdin和stdout进行操作。有一点我们需要注意,gets函数在读取字符串时将删除结尾的换行符('\n'),而puts函数在写入字符串时将在结尾添加一个换行符。

To show that there is nothing special about functions like fgets and fputs, here they are, copied from the standard library on our system:

   1    /* fgets:  get at most n chars from iop */
   2    char *fgets(char *s, int n, FILE *iop)
   3    {
   4        register int c;
   5        register char *cs;
   6 
   7        cs = s;
   8        while (--n > 0 && (c = getc(iop)) != EOF)
   9            if ((*cs++ = c) == '\n')
  10                break;
  11        *cs = '\0';
  12        return (c == EOF && cs == s) ? NULL : s;
  13    }
  14 
  15    /* fputs:  put string s on file iop */
  16    int fputs(char *s, FILE *iop)
  17    {
  18        int c;
  19 
  20        while (c = *s++)
  21            putc(c, iop);
  22        return ferror(iop) ? EOF : 0;
  23    }

下面的代码是标准库中fgets和fputs函数的代码,从中可以看出,这两个函数并没有什么特别的地方。代码如下所示:

   1    /* fgets:  get at most n chars from iop */
   2    char *fgets(char *s, int n, FILE *iop)
   3    {
   4        register int c;
   5        register char *cs;
   6 
   7        cs = s;
   8        while (--n > 0 && (c = getc(iop)) != EOF)
   9            if ((*cs++ = c) == '\n')
  10                break;
  11        *cs = '\0';
  12        return (c == EOF && cs == s) ? NULL : s;
  13    }
  14 
  15    /* fputs:  put string s on file iop */
  16    int fputs(char *s, FILE *iop)
  17    {
  18        int c;
  19 
  20        while (c = *s++)
  21            putc(c, iop);
  22        return ferror(iop) ? EOF : 0;
  23    }

For no obvious reason, the standard specifies different return values for ferror and fputs.

ANSI标准规定,ferror在发生错误时返回非0值,而fputs在发生错误时返回EOF,其他情况返回一个非负值。

It is easy to implement our getline from fgets:

   1    /* getline:  read a line, return length */
   2    int getline(char *line, int max)
   3    {
   4        if (fgets(line, max, stdin) == NULL)
   5            return 0;
   6        else
   7            return strlen(line);
   8    }

使用fgets函数很容易实现getline函数:

   1    /* getline:  read a line, return length */
   2    int getline(char *line, int max)
   3    {
   4        if (fgets(line, max, stdin) == NULL)
   5            return 0;
   6        else
   7            return strlen(line);
   8    }

Exercise 7-6. Write a program to compare two files, printing the first line where they differ.

练习7-6 编写一个程序,比较两个文件并打印它们第一个不相同的行。

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?

练习7-7 修改第5章的模式查找程序,使它从一个命名文件的集合中读取输入(有文件名参数时),如果没有文件名参数,则从标准输入中读取输入。当发现一个匹配行时,是否应该将相应的文件名打印出来?

Exercise 7-8. Write a program to print a set of files, starting each new one on a new page, with a title and a running page count for each file.

练习7-8 编写一个程序,以打印一个文件集合,每个文件从新的一页开始打印,并且打印每个文件相应的标题和页数。

TCPL/7.7_Line_Input_and_Output (2008-02-23 15:37:06由localhost编辑)