hudac
hudac

Reputation: 2798

fprintf() / std::cout doesn't print part of the string to stdout/stderr

I have this strange problem with stdout/stderr.

I want to apologize for not being able to put here the original code, it's too long / too many libraries dependent etc...
So please let me know if you ever encountered anything like it, or what may cause this issue without getting the original code, only the idea and examples of the simple things I tried to do:

In order to print, I use alignments, like the following:

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

While aString is a std::string. Sometimes I construct aString from std::ostringstream.
Sometimes I construct it with snprintf().

Please let me know if you know anything.


Illustration:

deadline_timer..... every 1 sec... my_print()
boost::asio::io_service.run

my_print() {

    for(std::map<>::iterator... begin, end, ++it....) {
        fprintf()s....
    }
}

Upvotes: 0

Views: 1537

Answers (3)

hudac
hudac

Reputation: 2798

I use boost::asio, I have a callback to read from stdin. this read is nonblocking - happens with async_read_some().
The problem was stdin was turned to be nonblocking, and it also caused stdout to be nonblocking as well because they point to the same file description (explanation).
It caused the fprintf() calls to fail (returned -1 with errno 11) and not all of the output got printed out on the screen.

It has no relation to boost.
I succeeded isolating the problem, the following code creates this problem:

#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;
}

If you'll comment the // Comment from here to // Comment untill here, it will print all of the output (fin and end will be printed).

One solution to this problem is to open another fd to the current tty using fopen(ttyname(STDOUT_FILENO), "w") and to print into it.
I believe another solution is to async_write() into screen.

Upvotes: 1

mksteve
mksteve

Reputation: 13073

Non printable characters may be breaking terminal.

fprintf(stdout,"%s", astdstring.cstr() );

Is how to print std::string

Upvotes: 1

mrflash818
mrflash818

Reputation: 934

The output might be stuck in a buffer, and not flushed before program termination.

Try adding exit(0) at the end of the program, and see if it helps.

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.

Upvotes: 0

Related Questions