使用 QTextStream 从控制台读取时出现访问冲突错误

Access violation error when using QTextStream to read from console

我有问题,在尝试使用 QTextStream 进行数据读取或写入控制台时遇到了访问冲突

First-chance exception at 0x77BD1D76 (ntdll.dll) in ApplicationStub.exe: 0xC0000005:
Access violation writing location 0x00000014.

Unhandled exception at 0x77BD1D76 (ntdll.dll) in ApplicationStub.exe: 0xC0000005:
Access violation writing location 0x00000014.

我的程序很简单:

#include <QtWidgets/QApplication>
#include <iostream>
#include <QTextStream>
#include <stdio.h>

using namespace std;

int main(int argc, char *argv[])
{

        QApplication app(argc, argv);

        ///////////////////////////////////////////////CONSOLE

        QTextStream out(stdout);
        out << "Please enter login username and password\n";
        out.flush();


        QTextStream in(stdin);
        QString line;
        in >> line;

        return app.exec();

}

可能是什么问题? 谢谢

编辑 1 我也试过 QCoreApplication 我正在使用 Visual studio 2013,Windows 7

我的 .pro 文件中还有:

QT += console
QT += core gui

我有 gui 选项,我想这应该没问题。

代码中完全没有问题,尽管它可以清理很多。很可能您没有将它构建为控制台应用程序,因此它在没有控制台的情况下启动,并且任何访问 non-existent 控制台的尝试都会失败。

评论:

  1. 要包含 Qt class Class,请使用 #include <QClass>,而不是 #include <QtModule/QClass>
  2. 您可以包含整个 Qt 模块以减少显式包含的数量,例如#include <QtCore> 对于控制台应用程序就足够了。
  3. 您不需要 QCoreApplication 实例即可使用 QTextStream(请注意 QApplication is-a QCoreApplication!)。
  4. stdoutstdin来自<cstdio>header。你不需要 <iostream>.
  5. 在项目文件以及您的代码中,您不需要添加模块依赖项,只需添加 top-level 模块即可。例如。如果您使用 core 以外的任何模块,则不需要显式添加 core 模块,因为所有其他模块都依赖于它。如果在Qt 5中添加了widgets模块,则不需要添加gui模块。等等。

有两种方法可以将控制台分配给您的进程:

  1. 在qmake工程文件中添加CONFIG += console。这样你的进程在启动时将始终有一个控制台 window:

    # test1.pro
    QT = core
    CONFIG += console c++11
    CONFIG -= app_bundle
    TARGET = test1
    TEMPLATE = app
    SOURCES += main.cpp
    

    您的代码现在可以正常工作:启动时,您会看到一个控制台 window 打开。

  2. 在 GUI 应用程序中显式分配控制台。控制台 window 仅在您需要时出现,默认情况下不会出现:

    # test1.pro
    QT = widgets      # or core if you don't care for a graphical interface
    CONFIG += c++11
    TARGET = test1
    TEMPLATE = app
    SOURCES += main.cpp
    

    main.cpp:

    #include <QtCore>
    #include <cstdio>
    #include <windows.h>
    
    void addConsole() {
      AllocConsole();
      freopen("CON", "wt", stdout);
      freopen("CON", "wt", stderr);
      freopen("CON", "rt", stdin);
    }
    
    int main() {
      addConsole();
      QTextStream out{stdout};
      QTextStream in{stdin};
    
      out << "Enter your name: " << flush;
    
      QString name;
      in >> name;
      out << "Your name is: " << name << "." << endl;
      QThread::sleep(1);
    }
    

重要提示

对项目文件进行任何更改后,您需要re-runqmake 重建项目。

为简化此操作,只需删除构建文件夹即可。