fprintf() / std::cout 不会将部分字符串打印到 stdout/stderr
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
行不存在时t 绘制,stdout
卡住(我的意思是,程序仍然有效,但没有任何内容打印到 stdout
再也没有。我不得不调用 std::cout.clear()
让它再次工作)。由于代码中的一个点,我无法掌握,std::cout.failbit
和 badbit
是 1
.
- 如果我 运行 带有
valgrind
的代码,则不会发生此行为。 valgrind
没说错。
- 如果我 运行 它与
gdb
它会发生,但 gdb
没有说错任何东西。
- 如果我 运行 它处于 IDE (
clion
) 调试模式,它不会发生。
- 如果我 运行 它在 IDE 中,没有调试,它就会发生。
- 我认为这取决于我在
fprintf()
中给出的对齐方式 printWidth
- 当 printWidth
较大时,它发生得更快(当它较小时,行 16
随机打印)。
- 另一件重要的事情:当有更多要打印时,它会更频繁地发生。
- 我试着给
std::cout
一个更大的缓冲区(不是他的默认值)但没有用。
- 我试图将所有输出缓冲到缓冲区中(而不是打印每一行),然后只
fprintf()
一次。发生相同的行为。
- 我在尝试打印
NULL
指针的代码中找不到任何地方。
- 我每隔
fprintf()s
使用 \n
打印,并在 my_print()
的末尾执行 fflush()
有知道的请告诉我
插图:
deadline_timer..... every 1 sec... my_print()
boost::asio::io_service.run
my_print() {
for(std::map<>::iterator... begin, end, ++it....) {
fprintf()s....
}
}
输出可能卡在缓冲区中,并且在程序终止之前未刷新。
尝试在程序末尾添加 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
我使用 boost::asio
,我有一个回调要从 stdin
读取。此读取是 nonblocking
- 发生在 async_read_some()
.
问题是 stdin
变成了 nonblocking
,它也导致 stdout
也变成了 nonblocking
,因为它们指向相同的文件描述 (explanation)。
它导致 fprintf()
调用失败(返回 -1 和 errno 11
)并且并非所有输出都打印在屏幕上。
与boost无关
我成功地隔离了问题,以下代码造成了这个问题:
#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()
进入屏幕。
我在使用 stdout
/stderr
时遇到了这个奇怪的问题。
我想为无法将原始代码放在这里而道歉,它太长/依赖的库太多等等...
因此,如果您遇到过类似的情况,或者在没有获得原始代码的情况下可能导致此问题的原因,请告诉我,仅提供我尝试做的简单事情的想法和示例:
- 我在
RHEL 6.3
上使用 - 我无法将问题隔离在这里,我将给出我所做的代码示例。
fprintf() / printf() / std::cout
一段时间后停止工作。 我使用boost::asio::io_service
和deadline_timer
来调用my_print()
函数。
此my_print()
函数每1 second
一些信息打印到屏幕。
g++ (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4)
为了打印,我使用对齐方式,如下所示:
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
行不存在时t 绘制,stdout
卡住(我的意思是,程序仍然有效,但没有任何内容打印到stdout
再也没有。我不得不调用std::cout.clear()
让它再次工作)。由于代码中的一个点,我无法掌握,std::cout.failbit
和badbit
是1
. - 如果我 运行 带有
valgrind
的代码,则不会发生此行为。valgrind
没说错。 - 如果我 运行 它与
gdb
它会发生,但gdb
没有说错任何东西。 - 如果我 运行 它处于 IDE (
clion
) 调试模式,它不会发生。 - 如果我 运行 它在 IDE 中,没有调试,它就会发生。
- 我认为这取决于我在
fprintf()
中给出的对齐方式printWidth
- 当printWidth
较大时,它发生得更快(当它较小时,行16
随机打印)。 - 另一件重要的事情:当有更多要打印时,它会更频繁地发生。
- 我试着给
std::cout
一个更大的缓冲区(不是他的默认值)但没有用。 - 我试图将所有输出缓冲到缓冲区中(而不是打印每一行),然后只
fprintf()
一次。发生相同的行为。 - 我在尝试打印
NULL
指针的代码中找不到任何地方。 - 我每隔
fprintf()s
使用\n
打印,并在my_print()
的末尾执行
fflush()
有知道的请告诉我
插图:
deadline_timer..... every 1 sec... my_print()
boost::asio::io_service.run
my_print() {
for(std::map<>::iterator... begin, end, ++it....) {
fprintf()s....
}
}
输出可能卡在缓冲区中,并且在程序终止之前未刷新。
尝试在程序末尾添加 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
我使用 boost::asio
,我有一个回调要从 stdin
读取。此读取是 nonblocking
- 发生在 async_read_some()
.
问题是 stdin
变成了 nonblocking
,它也导致 stdout
也变成了 nonblocking
,因为它们指向相同的文件描述 (explanation)。
它导致 fprintf()
调用失败(返回 -1 和 errno 11
)并且并非所有输出都打印在屏幕上。
与boost无关
我成功地隔离了问题,以下代码造成了这个问题:
#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()
进入屏幕。