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使得对远端的进程的处理就如同处理常规文件一样

原文地址:https://www.cnblogs.com/wizzhangquan/p/4082379.html