《C程序设计语言》------关于输入输出(stdin、stdout、stderr)
2012-04-02 22:39
429 查看
启动一个C语言程序时,操作系统环境负责打开三个文件,并将这3个文件的指针提供给该程序。这3个文件分别为标准输入(stdin)、标准输出(stdout)、标准错误(stderr)。它们在<stdio.h>中声明,大多数环境中,stdin指向键盘,stdout、stderr指向显示器。之所以使用stderr,若因某种原因造成其中一个文件无法访问,相应的诊断信息要在该链接的输出的末尾才能打印出来。当输出到屏幕时,这种处理方法尚可接受,但如果输出到一个文件或通过管道输出到另一个程序时,就无法接受了。若有stderr存在,即使对标准输出进行了重定向,写到stderr中的输出通常也会显示在屏幕上。
exit():在主程序main中,语句return expr等价于exit(expr)。但是,函数exit有一个优点,它可以从其他函数中调用,并且可以用查找程序查找这些调用。exit(0)为正常退出,exit(1)只要里面的参数不为零,为非正常退出,。
fgets:
fp指向的文件中读取下一个输入行(包括换行符),并将它存放在字符数组line中,最多读取maxline-1个字符。读取的行将以'\0'结尾,结尾保存到数组中。通常,fgets返回line,遇到文件结尾或发生错误,返回NULL。
晚上做了一个题,用去了很长时间,就因为一些简单错误,在此记录。《C程序设计语言》第2版(中文)P145 7-6:
编写一个程序,比较两个文件并打印它们第一个不相同的行。
错误1:将第35行写为:
这里明显混淆了数组与指针的关系,若为当做数组,实际是第一个数的地址,而不是整个数组。
错误2:第42行后,加了两句:
fp1、fp2实际是指向文件的文件描述符,不能做加减运算。按照我的本意是fp1自加后指向文件的下一行,实际上fgets函数读取下一行时已经加上换行符了。
fgets函数如下:
第7行写的很清楚,读了换行符。
总结经验:要先弄清函数各个参数的用法再动手,否则事倍功半。
exit():在主程序main中,语句return expr等价于exit(expr)。但是,函数exit有一个优点,它可以从其他函数中调用,并且可以用查找程序查找这些调用。exit(0)为正常退出,exit(1)只要里面的参数不为零,为非正常退出,。
fgets:
char *fgets(char *line, int maxline, FILE *fp);
fp指向的文件中读取下一个输入行(包括换行符),并将它存放在字符数组line中,最多读取maxline-1个字符。读取的行将以'\0'结尾,结尾保存到数组中。通常,fgets返回line,遇到文件结尾或发生错误,返回NULL。
晚上做了一个题,用去了很长时间,就因为一些简单错误,在此记录。《C程序设计语言》第2版(中文)P145 7-6:
编写一个程序,比较两个文件并打印它们第一个不相同的行。
#include <stdio.h> #define MAXSIZE 100 main(int argc, char *argv[]) { FILE *fp1, *fp2; void filecmp(FILE *, FILE *); char *prog = argv[0]; if (argc < 3) { fprintf(stderr, "error: no enough files!\n"); exit(1); } else { if ((fp1 = fopen(*++argv, "r")) == NULL) { fprintf(stderr, "%s: can't open %s\n", prog, *argv); exit(2); } else if ((fp2 = fopen(*++argv, "r")) == NULL) { fprintf(stderr, "%s: can't open %s\n", prog, *argv); exit(3); } else { filecmp(fp1, fp2); fclose(fp1); fclose(fp2); } } exit(0); } void filecmp(FILE *ifp1, FILE *ifp2) { char line1[MAXSIZE], line2[MAXSIZE]; int count = 0; int full = 0; while ((fgets(line1, MAXSIZE, ifp1) != NULL) && (fgets(line2, MAXSIZE, ifp2) != NULL)) { if ((strcmp(line1, line2)) == 0) { count++; full = 1; } else { fprintf(stdout, "The number of different line is %d\n", count); fprintf(stdout, "%s\n", line1); fprintf(stdout, "%s\n", line2); return; } } if (!full) fprintf(stderr, "error: cannont read!\n"); else fprintf(stderr, "same files!\n"); }
错误1:将第35行写为:
char *line1, *line2;
这里明显混淆了数组与指针的关系,若为当做数组,实际是第一个数的地址,而不是整个数组。
错误2:第42行后,加了两句:
fp1++; fp2++;
fp1、fp2实际是指向文件的文件描述符,不能做加减运算。按照我的本意是fp1自加后指向文件的下一行,实际上fgets函数读取下一行时已经加上换行符了。
fgets函数如下:
char *fgets(char *s, int n, FILE *fp) { register int c; register char *cs; while (--n > 0 && (c = getc(iop)) != EOF) if ((*cs++ = c) == '\n') break; *cs = '\0'; return (c == EOF && cs == s) ? NUll : s; }
第7行写的很清楚,读了换行符。
总结经验:要先弄清函数各个参数的用法再动手,否则事倍功半。
相关文章推荐
- 关于输入输出(stdin、stdout、stderr)
- Linux下如何重新打开标准输入输出(stdin,stdout,stderr)
- 关于STDIN,STDOUT,STDERR的图解分析
- python重定向sys.stdin、sys.stdout和sys.stderr
- 【转】stdin, stdout, stderr 以及重定向
- stdout stdin stderr
- 详解C语言中的stdin,stdout,stderr
- unix-stdin/stdout/stderr
- 对stdin/stdout/stderr进行保护
- stdin、stdout、stderr
- 【转】Unix/Linux下的stdout,stdin同stderr
- scripts: stdin, stdout和stderr的重定向的解释
- Three Standard Streams: stdin, stdout, stderr
- stdin, stdout, stderr 详解
- stdin stderr stdout
- linux下的stdin,stdout,stderr详解
- stdin,stderr,stdout
- Linux Shell 文件描述符 及 stdin stdout stderr 重定向
- 04 Linux Shell 文件描述符 及 stdin stdout stderr 重定向
- 详解C语言中的stdin,stdout,stderr