[英]fprintf() / std::cout doesn't print part of the string to stdout/stderr
我在stdout
/ stderr
奇怪的问题。
我很抱歉无法将原始代码放到这里,它太长/太多依赖库等...
因此,如果您遇到过类似的问题,或者在没有原始代码的情况下可能导致此问题的原因,请告诉我,仅提供我尝试做的简单事情的想法和示例:
RHEL 6.3
上使用g++ (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4)
fprintf() / printf() / std::cout
在一段时间后停止工作。 我使用boost::asio::io_service
与deadline_timer
以调用my_print()
函数。 my_print()
函数每隔1 second
在屏幕上打印一些信息。 为了打印,我使用对齐方式,如下所示:
fprintf(stdout, "%*s\n", -printWidth, someEnumToStr[i]);
fprintf(stdout, "%s\n", aString);
fprintf(stdout, "%u\n", num);
虽然aString
是std::string
。 有时我从std::ostringstream
构造aString
。
有时我用snprintf()
构造它。
std::map
信息,地图内恰好有16个元素。 我对其进行迭代,对于每个元素,我都尝试使用上面的fprintf()
示例打印数据。 16
的行。 stdout
重定向到文件( ./a.out > aaa.txt
),则元素16
的行将被打印。 FILE*
和fprintf()
到此文件,则再次打印所有内容(所有行,包括元素16
) fprintf()
之前,我尝试使用std::cout
(以及与std::cout.width(printWidth) << std::left
...的对齐),发生了相同的行为,但是未绘制第16
行, stdout
卡住了(我的意思是,程序仍然可以运行,但是什么也没打印到stdout
了。我必须调用std::cout.clear()
才能使其再次运行)。 由于代码中的一点我无法动手,因此std::cout.failbit
和badbit
为1
。 valgrind
运行代码,则不会发生此行为。 valgrind
没说错。 gdb
运行它,就会发生,但是gdb
不会说任何错误。 clion
)中运行它,则不会发生。 fprintf()
的对齐方式给出的printWidth
当printWidth
较大时,它发生得更快(当较小时,将随机打印第16
行)。 std::cout
一个更大的缓冲区(不是他的默认缓冲区),它没有用。 fprintf()
一次。 发生相同的行为。 NULL
指针。 \\n
每对夫妇的fprintf()s
,并做fflush()
在结束my_print()
如果您知道什么,请告诉我。
插图:
deadline_timer..... every 1 sec... my_print()
boost::asio::io_service.run
my_print() {
for(std::map<>::iterator... begin, end, ++it....) {
fprintf()s....
}
}
我使用boost::asio
,我有一个回调要从stdin
读取。 此读取是nonblocking
-发生在async_read_some()
。
问题是stdin
被变成nonblocking
,并且还导致stdout
也成为nonblocking
,因为它们指向相同的文件描述(说明) 。
这导致fprintf()
调用失败(使用errno 11
返回-1),并且并非所有输出都在屏幕上打印出来。
它与提升无关。
我成功隔离了问题,以下代码创建了此问题:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
using namespace std;
int main(int argc, char *argv[]) {
const int problem = 8000;
const int myBuffSize = 32000;
char *myBuff = new char[myBuffSize];
int myoffset = 0;
memset(myBuff, '-', myBuffSize);
int flags;
bool toogle = true;
bool running = true;
// Comment from here
if ((flags = fcntl(STDIN_FILENO, F_GETFL, 0)) < 0) {
printf("error fcntl()\n");
return 0;
}
if (fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK) < 0) {
printf("error fcntl()\n");
return 0;
}
// Comment until here
while(running) {
toogle = toogle ? false : true;
if (toogle) {
snprintf(myBuff + problem, myBuffSize - problem, "fin\n\n");
} else {
snprintf(myBuff + problem, myBuffSize - problem, "end\n\n");
}
fprintf(stdout, "%s", myBuff);
sleep(1);
}
delete[] myBuff;
return 0;
}
如果您要注释// Comment from here
到// Comment untill here
,它将打印所有输出(将显示fin
和end
)。
解决此问题的一种方法是使用fopen(ttyname(STDOUT_FILENO), "w")
将另一个fd
打开到当前tty
并打印到其中。
我相信另一种解决方案是将async_write()
导入屏幕。
输出可能会卡在缓冲区中,并且在程序终止前不会刷新。
尝试在程序末尾添加exit(0)
,看看是否有帮助。
http://www.cplusplus.com/reference/cstdlib/exit/
All C streams (open with functions in <cstdio>) are closed (and flushed, if buffered), and all files created with tmpfile are removed.
不可打印字符可能会中断终端。
fprintf(stdout,"%s", astdstring.cstr() );
是如何打印std::string
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.