使用Qt,如何检查stdin是否为空?

时间:2017-09-02 19:23:33

标签: qt stdin

我有一个Qt程序来处理这样的stdin数据:

QTextStream qtin(stdin);
QString stdindata = qtin.readAll();
QByteArray ba;
ba = stdindata.toUtf8();
QJsonDocument exJSONDoc(QJsonDocument::fromJson(ba));
QJsonObject extRoot;
extRoot = exJSONDoc.object();
QStringList keys;
keys = extRoot.keys();
for (int n=0; n <= keys.count()-1; n++)
{
    qDebug() << extRoot.value(keys[n]).toString();
}

当我按照这样的方式调用我的程序时,它会起作用:

myprogram < ./data.json

但如果我在没有任何“&lt;”的情况下调用它它挂在qtin.readAll()

如果标准输入为空,我如何查询Qt?

2 个答案:

答案 0 :(得分:3)

(我假设一个Linux - 或者至少是POSIX-操作系统)

QTextStream qtin(stdin);
QString stdindata = qtin.readAll();

这将读取stdin直到达到文件结尾。因此可以使用重定向输入,如

myprogram < ./data.json
  

但如果我在没有任何“&lt;”的情况下调用它它挂起......

然后(也就是说,如果你单独运行myprogram stdin 而不是为空。它与你的shell的stdin相同。作为前台工作的程序正在等待您输入的终端上的输入(另请参阅tty(4))。尝试(在这种情况下)在终端上键入一些输入(您可以用 Ctrl D 结束以产生文件结束条件)。阅读job controltty demystified,另请参阅termios(3)

也许你可以用例如STDIN_FILENO上的isatty(3)。但这不会检测到pipe(7)之类的

tail -55 somefile | myprogram

你需要为你定义一个空的标准输入。我不知道这对你意味着什么,我会想到myprogram < /dev/null(参见null(4))作为获得空标准的方法。

也许您应该设计myprogram以便某些程序 选项(可能--ignore-stdin)避免从标准输入读取任何内容。

答案 1 :(得分:2)

这里的问题是readAll。见documentation

  

读取流的全部内容,并将其作为 QString 返回。   处理大文件时避免使用此功能,因为它会占用大量文件   大量的记忆。

因此它会在遇到文件结束时读取stdin,并且由于stdin与控制台关联,因此您必须发出文件结束信号。通常是Ctrl-D并按回车键。

您更有可能逐行阅读stdin。 使用户文本编辑控制台只能逐行传输数据到应用程序的标准输入。这个设计就像很久以前计算机只有一台打印机作为用户界面(没有屏幕)。

<小时/> 现在的问题是如何在没有文件末尾信息的情况下阅读与控制台连接的JSon表格stdin控制台?

我会使用一些SAX解析器,但这对你来说很复杂。 那么还有另一种检测JSon结束的方法吗?

你可以尝试这种方法(这是基本的想法,而不是最终的解决方案,因此它有几个缺点):

QFile file(stdin);
QByteArray data = file.peak(largeNumber);
QJsonParseError error;
QJSonDocument doc = QJSonDocument::fromJson(data, &error);
while (!doc.isValid() && JSonNotTerminatedError(error.error))
{
    // TODO: wait for new data - it would be best to use readyRead signal
    doc = QJSonDocument::fromJson(data, &error);
}

其中JSonNotTerminatedError对于与未终止的JSon数据相关的各个QJsonParseError::ParseError values(请参阅链接文档)返回true。

现在我看到QFile没有必要的构造函数,但主要概念应该是明确的。从stdin读取数据并检查它是否是有效的JSon文档。