zoukankan      html  css  js  c++  java
  • stdin、stdout、stderr

    启动一个C语言程序时,操作系统环境负责打开三个文件,并将这3个文件的指针提供给该程序。这3个文件分别为标准输入(stdin)、标准输出(stdout)、标准错误(stderr)。它们在stdio.h中声明,大多数环境中,stdin指 ...
     
     

    启动一个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:

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

     fp指向的文件中读取下一个输入行(包括换行符),并将它存放在字符数组line中,最多读取maxline-1个字符。读取的行将以''结尾,结尾保存到数组中。通常,fgets返回line,遇到文件结尾或发生错误,返回NULL。

    晚上做了一个题,用去了很长时间,就因为一些简单错误,在此记录。《C程序设计语言》第2版(中文)P145 7-6:

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

     1 #include <stdio.h>
    2
    3 #define MAXSIZE 100
    4
    5 main(int argc, char *argv[])
    6 {
    7 FILE *fp1, *fp2;
    8 void filecmp(FILE *, FILE *);
    9 char *prog = argv[0];
    10
    11 if (argc < 3) {
    12 fprintf(stderr, "error: no enough files! ");
    13 exit(1);
    14 }
    15 else {
    16 if ((fp1 = fopen(*++argv, "r")) == NULL) {
    17 fprintf(stderr, "%s: can't open %s ", prog, *argv);
    18 exit(2);
    19 }
    20 else if ((fp2 = fopen(*++argv, "r")) == NULL) {
    21 fprintf(stderr, "%s: can't open %s ", prog, *argv);
    22 exit(3);
    23 }
    24 else {
    25 filecmp(fp1, fp2);
    26 fclose(fp1);
    27 fclose(fp2);
    28 }
    29 }
    30 exit(0);
    31 }
    32
    33 void filecmp(FILE *ifp1, FILE *ifp2)
    34 {
    35 char line1[MAXSIZE], line2[MAXSIZE];
    36
    37 int count = 0;
    38 int full = 0;
    39
    40 while ((fgets(line1, MAXSIZE, ifp1) != NULL) &&
    41 (fgets(line2, MAXSIZE, ifp2) != NULL)) {
    42 if ((strcmp(line1, line2)) == 0) {
    43 count++;
    44 full = 1;
    45 }
    46 else {
    47 fprintf(stdout, "The number of different line is %d ", count);
    48 fprintf(stdout, "%s ", line1);
    49 fprintf(stdout, "%s ", line2);
    50 return;
    51 }
    52 }
    53 if (!full)
    54 fprintf(stderr, "error: cannont read! ");
    55 else
    56 fprintf(stderr, "same files! ");
    57 }

    错误1:将第35行写为:

    char *line1, *line2;

    这里明显混淆了数组与指针的关系,若为当做数组,实际是第一个数的地址,而不是整个数组。

    错误2:第42行后,加了两句:

    fp1++;
    fp2++;

    fp1、fp2实际是指向文件的文件描述符,不能做加减运算。按照我的本意是fp1自加后指向文件的下一行,实际上fgets函数读取下一行时已经加上换行符了。

    fgets函数如下:

     1 char *fgets(char *s, int n, FILE *fp)
    2 {
    3 register int c;
    4 register char *cs;
    5
    6 while (--n > 0 && (c = getc(iop)) != EOF)
    7 if ((*cs++ = c) == ' ')
    8 break;
    9 *cs = '';
    10 return (c == EOF && cs == s) ? NUll : s;
    11 }

    第7行写的很清楚,读了换行符。

    总结经验:要先弄清函数各个参数的用法再动手,否则事倍功半。

    关于 stdin、stdout、stderr 的说明如下:

    By default, standard input is read from the keyboard, while standard output and standard error are printed to the screen

    默认情况下,标准输入从键盘读取,同时标准输出和标准错误会打印到屏幕。

    在控制台测试 :

    void main( void )
    {
    fprintf(stderr, "%s:%d", __FILE__, __LINE__);
    system("pause");
    }

    会在屏幕显示当前文件的路径和fprintf语句所在的行数。 ^_^
  • 相关阅读:
    centos7内存处理
    MySQl分析工具之mysqltuner.pl及mysqlslap
    Mycat-web 安装
    【NOI2001】【Luogu P2704】【POJ1185】炮兵阵地
    【OpenJudge 7834】分成互质组
    Assignment(单调队列)
    OO’s Sequence
    【注意】邻接表
    20190405模拟测试
    【USACO2010open】时间旅行
  • 原文地址:https://www.cnblogs.com/timssd/p/4078073.html
Copyright © 2011-2022 走看看