How do I read stdin to the end in qt?

I have a qt application that can be called with

cat bla.bin  | myapp

      

Easiest way to read all input (stdin) into QByteArray on Win, Mac and Linux?

I'm tired of a few things, but none of them work (on windows):

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    QByteArray content;

    //---Test 1: hangs forever, reads 0
    while(!std::cin.eof()) {
        char arr[1024];
        int s = std::cin.readsome(arr,sizeof(arr));
        content.append(arr,s);
    }

    //---Test 2: Runs into timeout
    QFile in;
    if(!in.open(stdin,QFile::ReadOnly|QFile::Unbuffered)) {
        qDebug() << in.errorString();
    }
    while (in.waitForReadyRead(1000)) {
        content+=in.readAll();
    }
    in.close();

    return app.exec();
}

      

Do I have a problem with Event-Loop or does it not work without?

+3


source to share


1 answer


The main problem with actually reading from stdin

is usage readsome

. readsome

usually not used for reading from files (including stdin). readsome

commonly used for binary data in asynchronous sources. Technically speaking, eof

it is not installed with readsome

. read

differs in this respect as it sets eof

accordingly. There is a SO question / question here that might be of interest. If you support Linux and Windows and are reading stdin, you should be aware that Windows stdin

does not open in binary mode (none stdout

). On Windows, you will have to use _setmode

on stdin

. One way to do this is #ifdef

with Q_OS_WIN32

. Using QFile does not solve this problem.

In the code you are trying to create, you do not see that you are interested in the actual event loop. You can still use QT objects like QByteArray without an event loop. In your code, you read data from stdin ( cin

) and then you have executed return app.exec();

which puts your console application in a loop waiting for events. You haven't added any events to the QT event queue before app.exec();

, so the only thing you can do is end your application with control-c. If no event loop is required, code is sufficient, for example:



#include <QCoreApplication>
#include <iostream>

#ifdef Q_OS_WIN32
#include <fcntl.h>
#include <io.h>
#endif

int main()
{
    QByteArray content;

#ifdef Q_OS_WIN32
    _setmode(_fileno(stdin), _O_BINARY);
#endif

    while(!std::cin.eof()) {
        char arr[1024];
        std::cin.read(arr,sizeof(arr));
        int s = std::cin.gcount();
        content.append(arr,s);
    }
}

      

Note that we used QByteArray

but did not have a QCoreApplication app(argc, argv);

callapp.exec();

+2


source







All Articles