• Linuc学习3-输入和输出重定向


    已打开的文件描述符在fork和exec调用后保留下来,我们可以利用对进程这方面知识点的理解来改变程序的行为。

    这个例子涉及一个过滤程序:它从标准输入读取数据,然后向标准输出写数据,同时在输入和输出之间对数据做些有用的转换。

    过滤程序upper.c

    #include<stdio.h>
    #include<stdlib.h>
    #include<ctype.h>
    int main()
    {
        int ch;
        while( EOF != (ch=getchar()))
        {
            putchar(toupper(ch));
        }
        exit(0);    
    
    }

    upper.c执行效果:

     

    如果我们利用shell从定向把一个文件的内容全部转为大写,如下所示:

    如果我们想在另一个程序中使用这个过滤程序会发生什么呢?下一个例子useupper.c接受一个文件名做命令行参数,若果对它调用不正确,他将会响应一个错误信息。

    #include<unistd.h>
    #include<stdio.h>
    #include<stdlib.h>
    int main(int argc,char *argv[])
    {
        char *filename;
        int i;
        if(argc != 2)
        {
            fprintf(stderr,"usage :useupper file
    ");
            exit(1);
        }
        filename = argv[1];
    //重新打开标准输入,并再次检查有无错误发生,然后用execl调用upper程序。
    for (i = 0;i<argc;i++) { printf("the argv[%d] is %s ",i,argv[i]); } if(!freopen(filename,"r",stdin)) { fprintf(stderr,"can't redirect stdin from file %s! ",filename); exit(2); } execl("./upper","upper",0); //execl会替换当前的进程。如果没有发生错误,剩下的语句不会执行。 perror("could not exec ./upper"); exit(3); }

    分析一下这个程序的流程:

    运行时我们应该给他提供一个文件,让他把文件的内容全部转换为大写。这项工作由upper程序完成,但它不会处理文件名参数。注意,我们不需要upper程序的源代码。我们可以利用这种方法

    运行任何可执行程序。

    useupper程序用freopen函数先关闭标准输入,然后将文件流stdin与程序参数给定的文件名关联起来。接下来,它调用execl用upper程序替换掉正在运行的进程代码。有hi那我IE已打开的文件描述符会在execl调用

    之后保留下来,所以upper程序的运行情况和他在shell提示符下运行情况完全一致。 

     ps:

    1.
    stdout(Standardoutput)标准输出
    stdin(Standardinput)标准输入
    stderr(Standarderror)标准错误

    2.int fprintf (FILE* stream, const char*format, [argument])

    FILE*stream:文件指针
    const char* format:输出格式
    argument  :附加参数列表
     
    作用:
    fprintf( )会根据参数format 字符串来转换并格式化数据, 然后将结果输出到参数stream 指定的文件中, 直到出现字符串结束('')为止。
     

    3.FILE *freopen(const char * restrict filename, const char * restrict mode, FILE * restrict stream);

    freopen是被包含于C标准库头文件<stdio.h>中的一个函数,用于重定向输入输出流。该函数可以在不改变代码原貌的情况下改变输入输出环境,但使用时应当保证流是可靠的。

    形参说明:

    filename:需要重定向到的文件名或文件路径。
    mode:代表文件访问权限的字符串。例如,"r"表示“只读访问”、"w"表示“只写访问”、"a"表示“追加写入”。
    stream:需要被重定向的文件流。
    返回值:如果成功,则返回该指向该输出流的文件指针,否则返回为NULL。

    4.perror()

    perror(s) 用来将上一个函数发生错误的原因输出到标准设备(stderr)。参数 s 所指的字符串会先打印出,后面再加上错误原因字符串。此错误原因依照全局变量errno(这里的说法不准确,errno是一个宏,该宏返回左值) 的值来决定要输出的字符串。
    在库函数中有个errno变量,每个errno值对应着以字符串表示的错误类型。当你调用"某些"函数出错时,该函数已经重新设置了errno的值。perror函数只是将你输入的一些信息和现在的errno所对应的错误一起输出。

     

    以上内容来自《Linux程序设计第四版》PS部分来自百度百科

  • 相关阅读:
    DBCP数据库连接池
    Java Ant build.xml详解
    AWK 用法
    java打jar包
    linux 下java jar包的方法
    linux下java命令行引用jar包
    java webservice
    设计模式的几大原则
    ContextLoaderListener
    WebApplicationContextUtils源码
  • 原文地址:https://www.cnblogs.com/xiaodeyao/p/6440615.html
Copyright © 2020-2023  润新知