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?
source to share
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();
source to share