在一个X函数中,如果一个Fd,然后缓冲区完成,我使用pipe道来缓冲(printf的几个,打印在Y函数里面从X函数调用的内部)的stdoutstream,closures一个pipe道和其他Fd,然后使用printf就可以了。
我想要完全确定缓冲区是空的,当下次再次调用这个X函数来完成任务时。 我尝试了几个我在网上find的东西:
fflush
ioctl
, _flushlbf
:貌似不被gcc支持。 g ++支持它吗? fseek(stdin,EOF,SEEK_END);
fpurge(ofp);
我调用X()
函数,几次。 现在的代码,我写了,如果下一组输出大于以前的设置,工作正常。
如果下一组输出less于当前输出组。 然后下一个集合有一些额外的垃圾值,这给我一个迹象,该缓冲区可能没有完全刷新。
由于某些原因,我用C编写了完整的代码,但使用了g ++编译器。
我的代码如下:
void X(int pairs,char* expOut) { char buf[256]; int fds[2]; char output[300]; char input[50]; /* opening pipes */ pipe(fds); /* saving the the given stdout stream */ int bak = dup(STDOUT_FILENO); /* associating Fds[1] pipe with stdout */ int res=dup2(fds[1],STDOUT_FILENO); /* associating Fds[0] pipe with stdin */ dup2(fds[0],STDIN_FILENO); assert(res!=-1); /* Call To function Y: function combParenthesis is a recursive function, which prints out some strings couple of time */ combParenthesis(pairs) ; fflush(stdout); /* closing stdout FD stream */ close(fds[1]); fflush(stdout); /* restoring the old stdout stream */ dup2(bak, 1); close(bak); /* opening, stdin stream for reading */ FILE *ofp = fdopen(fds[0], "r"); char strs[30][30]; for (int i=0;i<30;i++) { memset(strs[i], 0, 30); } int i=0; if (ofp) { int sz; if((pairs*2)+1 <= 1) { sz=5; } else {sz = (pairs*2)+1 ;} /* read the stream line by line */ while (fgets(buf,sz ,ofp)) { printf("\n next string %s", buf); i++; } if (ferror(ofp)) { printf("something went wrong in the input to printf"); } } /* different ways to flush it out */ char c; while( (c = fgetc( ofp )) != EOF && c != '\n' ); fseek(stdin,EOF,SEEK_END); fpurge(ofp); fclose(ofp); fflush(stdin); // _flushlbf(); /* close the fd associated with stdin */ close(fds[0]); }
编辑:在fflush
定位结束的精度。
我设法运行你的代码只需使用我自己的combParenthesis
(第一遍:中等字符串,第二:更大的字符串,第三小)。 我从来没有在输出中发现垃圾…只要我已经替换了你的printf("\n next string %s", buf);
由stderr
上的stderr
fprintf(stderr, "\n next string %s", buf);
我也得到了正确的输出,通过刷新标准输出之后stdin和ofp由一个单一的fflush(stdout)
。 恕我直言,问题是:
printf("\n next string %s", buf)
在stdout上编写,stdout可能会被缓冲 以下是我找到的主要改进:
combParenthesis
输出,则不要在任何地方写入stdout(或者确保将其刷新) dup2(fds[0],STDIN_FILENO);
因为你直接读到管道的另一端(哪个更好) sz = (pairs*2)+1
是否小于sizeof(buf)
编辑:事实上,我刚刚意识到你的代码可以工作,甚至在应用程序的其他地方混合使用printf
,只要你在将它复制到fds 之前刷新标准输出[1]。
所以这里是你的X()
函数的固定版本,有明确的编辑(但恕我直言,你应该考虑我的其他建议):
void X(int pairs,char* expOut) { char buf[256]; int fds[2]; char output[300]; char input[50]; /* BEGIN EDIT */ /* first flush stdout */ fflush(stdout); /* END EDIT */ /* opening pipes */ pipe(fds); /* saving the the given stdout stream */ int bak = dup(STDOUT_FILENO); /* associating Fds[1] pipe with stdout */ int res=dup2(fds[1],STDOUT_FILENO); /* associating Fds[0] pipe with stdin */ dup2(fds[0],STDIN_FILENO); assert(res!=-1); /* Call To function Y: function combParenthesis is a recursive function, which prints out some strings couple of time */ combParenthesis(pairs) ; /* closing stdout FD stream */ close(fds[1]); fflush(stdout); /* restoring the old stdout stream */ dup2(bak, 1); close(bak); /* opening, stdin stream for reading */ FILE *ofp = fdopen(fds[0], "r"); char strs[30][30]; for (int i=0;i<30;i++) { memset(strs[i], 0, 30); } int i=0; if (ofp) { int sz; if((pairs*2)+1 <= 1) { sz=5; } else {sz = (pairs*2)+1 ;} /* read the stream line by line */ // EDIT : changed sz with sizeof(buf)-1 - cause: no correct pairs value while (fgets(buf, sizeof(buf) - 1,ofp)) { printf("\n next string %s", buf); i++; } if (ferror(ofp)) { printf("something went wrong in the input to printf"); } } /* different ways to flush it out */ /* BEGIN EDIT : ALL FLUSHING COMMENTED OUT char c; while( (c = fgetc( ofp )) != EOF && c != '\n' ); fseek(stdin,EOF,SEEK_END); fpurge(ofp); fclose(ofp); fflush(stdin); // _flushlbf(); END EDIT */ /* close the fd associated with stdin */ close(fds[0]); }
即使输出重定向到一个文件,我也从不在垃圾中读取,但是由于我无法解释的原因,消息的顺序并不是我所期望的。 希望这不是你的担忧