繁体   English   中英

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_servicedeadline_timer以调用my_print()函数。
    my_print()函数每隔1 second在屏幕上打印一些信息。

为了打印,我使用对齐方式,如下所示:

fprintf(stdout, "%*s\n", -printWidth, someEnumToStr[i]);
fprintf(stdout, "%s\n", aString);
fprintf(stdout, "%u\n", num);

虽然aStringstd::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.failbitbadbit1
  • 如果我使用valgrind运行代码,则不会发生此行为。 valgrind没说错。
  • 如果我用gdb运行它,就会发生,但是gdb不会说任何错误。
  • 如果在调试模式下在IDE( clion )中运行它,则不会发生。
  • 如果我在IDE中运行它而没有调试,则会发生。
  • 我认为这取决于我为fprintf()的对齐方式给出的printWidthprintWidth较大时,它发生得更快(当较小时,将随机打印第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 ,它将打印所有输出(将显示finend )。

解决此问题的一种方法是使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM