• Linux_C bc/利用2根管道让2进程通讯


     1 /* tingbc.c
     2  * use two pipe to execute the bc.
     3  * one pipe: todc[2] , another: fromdc[2]
     4  * child thread to do dc, parent do UI
     5  */
     6 
     7 #include <stdio.h>
     8 #include <unistd.h>
     9 #include <string.h>
    10 #define oops(x, n) {perror(x); exit(n);}
    11 
    12 void be_dc(int todc[], int fromdc[]);
    13 void be_bc(int todc[], int fromdc[]);
    14 int main(void) {
    15   int todc[2], fromdc[2], pid;
    16   if(pipe(todc)==-1 || pipe(fromdc)==-1)
    17     oops("pipe", 2);
    18   if((pid=fork()) == -1)
    19     oops("fork" ,3);
    20   if(pid==0) {
    21     be_dc(todc, fromdc);//child do dc
    22   }else{
    23     be_bc(todc, fromdc);//parent do UI
    24     wait(NULL);
    25   }
    26   return 0;
    27 }
    28 
    29 void be_dc(int todc[], int fromdc[]){
    30   //will do dc() , change the stdin to todc[1], change the stdout to fromdc[0]
    31   close(todc[1]);
    32   close(fromdc[0]);
    33   if(dup2(todc[0], 0)==-1)
    34     oops("could not redirect the stdin", 4);
    35   if(dup2(fromdc[1], 1)==-1)
    36     oops("could not redirct the stdout", 5);
    37   close(todc[0]);
    38   close(fromdc[1]);
    39   execlp("dc", "dc", "-",NULL);
    40   oops("exe",1);
    41 }
    42 
    43 void be_bc(int todc[], int fromdc[]){
    44   //will do bc(), change the stdout to todc[1], and use the fromdc[0] to read the dc's result
    45   char cmdbuf[BUFSIZ];
    46   int c1, c2;
    47   char operator;
    48   FILE *fout, *fread; 
    49   close(todc[0]);   //donot need to todc out
    50   close(fromdc[1]);  //donot need to fromdc in  
    51   
    52   fout=fdopen(todc[1],"w");  //write the todc[1]
    53   fread=fdopen(fromdc[0],"r" );     //read the dc's result from fromdc[0]
    54   
    55   while((printf("tinybc: ")) && (fgets(cmdbuf, BUFSIZ, stdin )!=-1)) {
    56     if( sscanf(cmdbuf, "%d %c %d", &c1,&operator,&c2) !=3) {
    57       printf("syntax error.
    ");
    58       continue;
    59     }
    60     printf("2u cin is %d %c %d
    ", c1,operator,c2);
    61     if(fprintf(fout, "%d
    %d
    %c
    p
    ", c1,c2,operator) == EOF)//在这里有问题,c1总是读不进去,一直是0.
    62       oops("fprintf", 6);
    63     
    64     fflush(fout);
    65     if(fgets(cmdbuf, BUFSIZ, fread)==NULL)
    66       break;
    67     printf("%d %c %d = %s", c1, operator, c2, cmdbuf);
    68   }
    69   close(todc[0]);
    70   close(fromdc[1]);
    71 }

    这里,在2个pipe使用时,要分清楚pipe[0],pipe[1]哪一个是读出哪一个是写入。

    同时这里用到了sscanf函数。

    /**********************************************************************************************/

    sscanf(格式化字符串输入)
    相关函数 scanf,fscanf
    表头文件 #include<stdio.h>
    定义函数 int sscanf (const char *str,const char * format,........);
    函数说明 sscanf()会将参数 str 的字符串根据参数 format 字符串来转换并格
    式化数据。格式转换形式请参考 scanf()
    。转换后的结果存于对应
    的参数内。
    返回值
    成功则返回参数数目,失败则返回-1,错误原因存于 errno 中。
    范例
    #include<stdio.h>
    main()
    {
    int i;
    unsigned int j;
    char input[ ]=”10 0x1b aaaaaaaa bbbbbbbb”;
    char s[5];
    sscanf(input,”%d %x %5[a-z] %*s %f”,&i,&j,s,s);
    printf(“%d %d %s ”,i,j,s);
    }

    /***************************************************************************************/

    fdopen函数

    fdopen函数与fopen类是,返回一个FILE*类型值,不同的是此函数以文件描述符而非文件作为参数。

    使用fopen的时候,将文件名作为参数传给它。fopen可以打开设备文件也可以打开常规的磁盘文件。如只知道文件描述符而不清楚文件名的时候可以使用fdopen。

    使用fdopen使得对远端的进程的处理就如同处理常规文件一样

  • 相关阅读:
    RocketMq(三、重试机制)
    RocketMq(二、生产者、消费者demo)
    VUE(四、ajax-axios)
    配置git DiffMerge工具
    Gerrit 删除项目
    html元素
    UML类图细节
    json 转 javaBean
    将文件的编码格式转换为utf-8
    第四篇:Eclipse Android app 工程迁移到 Android Studio
  • 原文地址:https://www.cnblogs.com/wizzhangquan/p/4082379.html
Copyright © 2020-2023  润新知