当前位置:  技术问答>linux和unix

to:wwwunix : 这个问题该解决那?非常感谢!!!

    来源: 互联网  发布时间:2016-04-25

    本文导语:  我便写的一个bc计算器 这个程序有bug,当两个操作数的结果大于4096个字节时,一次打印不出全部结果,管道此时阻塞,下一次再执行计算的时候不能得出正确结果。 所以我在程序上加入了一个while语句,希望把管道...

我便写的一个bc计算器
这个程序有bug,当两个操作数的结果大于4096个字节时,一次打印不出全部结果,管道此时阻塞,下一次再执行计算的时候不能得出正确结果。
所以我在程序上加入了一个while语句,希望把管道的内容全部打印出来,但是发现程序跳不出来了,不能再次计算了,请问这是什么原因。(while语句见我的注视。

#include 
#include 
#define oops(m,x)  {perror(m); exit(x);}

main()
{
int pid,todc[2],fromdc[2];
//make two pipes
if(pipe(todc)==-1||pipe(fromdc)==-1)
oops("get pipe failed.",1);
//get a process for user interface
if((pid=fork())==-1)
oops("fork failed ",2);

if(pid==0)          //child is dc
be_dc(todc,fromdc);
else{                //parent is ui

be_bc(todc,fromdc);
wait(NULL); //wait for child
}
}

void be_dc(int in[2],int out[2])
{
close(in[1]);
close(out[0]);

if(dup2(in[0],0)==-1) //copy read end to 0
oops("dc:cannot redirect stdin ",3);
close(in[0]); //moved to fd 0

if(dup2(out[1],1)==-1) //dupe write end to 1
oops("dc:cannot redirect stdout",4);
close(out[1]); //moved to 1

execlp("dc","dc","-",NULL);
oops("cannot run dc",5);
}

void be_bc(int todc[2],int fromdc[2])
//从stdin读,然后转换成RPN,传送给pipe,然后
//从其他管道读入,并打印出


{

int num1,num2;
char operation[BUFSIZ],*fgets();
char message[BUFSIZ];
FILE *fpout ,*fpin;
int n_read;
close(todc[0]);
close(fromdc[1]);

fpout=fdopen(todc[1],"w");
fpin=fdopen(fromdc[0],"r");
if(fpout==NULL||fpin==NULL)
fatal("Error convering pipes to streams");
//main loop
while(printf("tinybc:"),fgets(message,BUFSIZ,stdin)!=NULL)
{
if(sscanf(message,"%d%[+-*/^]%d",&num1,operation,&num2)!=3)
{printf("syntax errorn");
continue;
}

if(fprintf(fpout,"%dn%dn%cnpn",num1,num2,*operation)==EOF)
fatal("Error writing");
fflush(fpout);

if(fgets(message,BUFSIZ,fpin)==NULL)
break;
printf("%d%c%d=%s",num1,*operation,num2,message);
/*
这里有个小 bug,当我的执行完一个运算的时候,不能跳出继续另一个运算,这是怎么回事阿?
我觉得问题就在这个while语句中。请高人指点。。。
*/


while(fgets(message,BUFSIZ,fpin)!=NULL)
{
printf("%s",message);
}
}
fclose(fpout);
fclose(fpin);

}

fatal(char *mess[])
{
fprintf(stderr,"Error :%sn",mess);
exit(1);
}


|
管道有个缓存大小,你一定写超过4096的时候一次就写不全了,所以你一次读也就不能读出全部的结果了。

你循环读的时候需要判断要读多长的数据,因为管道本身的读写都没有界定数据边界的机制,你必须自己知道要读多长数据,或是根据读到的内容判断是否已经收完了本次数据。

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • to wwwunix(yangying76@263.net) :我把贴子转到c++论坛了
  • wwwunix(木易) 请来拿分…… 01
  • wwwunix(木易) 请来拿分……
  • wwwunix(木易) 请来拿分…… 02
  • wwwunix(木易) 请来拿分…… 04
  • 为什么多线程调用不成?wwwunix和blh快来看啊!!


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3