Why isn't my C++/Qt program doing anything? - c++

I wrote this program in Qt Creator but I'm not sure how to run it. Here is my code:
#include <QtCore/QCoreApplication>
using namespace std;
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
string str;
cin >> str;
cout << " str is : " << str;
return a.exec();
}
When I run it my console shows this:
Starting /home/hamed/qt programs/test3-build-desktop/test3...
...and nothing happens. What should I do?

When copy pasting your code, it runs for me as expected (well, it doesn't terminate, but runs). Here is what I did in command line:
cd testproject
qmake -project
qmake
make
./testproject
As mentioned in the comment above, Qt itself is a library, so you are probably referring to some IDE when saying running it from "within Qt" - behaviour there is solely dependent on what IDE you are using.
Update:
From your message
Starting /home/hamed/qt programs/test3-build-desktop/test3...
I assume that you are using the QtCreator IDE, which does not allow you to enter things to console when running. I don't know whether you can get it to do so, but it works if you enter your project directory in console and use ./projectname. The building part mentioned above will be handled by QtCreator.
Another update:
Check out this thread for information on how to get it to work directly from QtCreator.

nothing happens!!
Your program is expecting an input, as you written here:
cin >> str;
what should i do?
Just type in something and press enter.

Add QTimer::singleShot(0, &a, SLOT(quit())); before the line return a.exec(); and don't forget to #include <QtCore/QTimer> (or you can make life easier and import the everything #include <QtCore>).
The a.exec() enters an event loop which waits for an event; normally in the form of user input with a graphical user interface. This however is a command line program and there isn't really a way for a user to send an event so it sits and waits forever. This is useful for server type applications but not what you're doing here. :)
(Note, this is one of many reasons your application might appear to be doing nothing. You may need to follow several of these answers before your program does what you expect)

Related

QProcess does not signal stdout ready

When I launch xfreerdp process out of shell, it prints INFO messages to stdout and WARN/ERROR messages to stderr, as expected (this is just the default /log-level:info mode).
However, when I launch it via QProcess, the QProcess only signals with readyReadStandardError(), i.e. allowing me to read WARN/ERROR messages but never signals with readyReadStandardOutput(). Only when the process finishes (I close the xfreerdp window), the signal is emitted by QProcess and all the stdout is read by me (I have no idea, where was it kept all the way long?)
I have found two topics concerning the problem:
Qt: How to get live output of a running QProcess
stdout from QProcess is nowhere near realtime
I tried solutions proposed there:
1). I tried to use QIODevice::ReadWrite | QIODevice::Unbuffered as the third argument of QProcess::start(). It did not help -- same as it is described by the links.
2). I tried to call QProcess::readAllStandardOutput() every 100ms using QTimer. However, when I read this way, the output byte array is always empty (until the process is finished). So again, same as told by by the links, it did not help.
When I launch xfreerdp with QProcess with /log-level:debug or /log-level:trace, the problem does not hold. I get signals of stdout being ready. But there are lots and lots of DEBUG/TRACE messages.
I search for a way to solve the problem. But if I don't find it, I have two options: either to use the default /log-level:info option or /log-level:debug option. The first one is preferable for me but I am afraid that all that stdout is stuck somewhere and I would get with an overflow of some buffer and the whole thing would crash or it would be like a memory leak (maybe, I will try to explore QProcess source code). The second one is so here, probably, a better option, but the debug mode of xfreerdp is really quite too verbose.
UPDATE with the minimal reproducible example:
Alas, one need a vm to connect to.
If one launches the example (I have checked on Fedora 35 and Fedora 33), one will see that xfreerdp will output the INFO messages only after one will close the xfreerdp window, i.e., only after the process finishes.
//
// main.cpp
// g++ -o main main.cpp -std=c++11 -I/usr/include/qt5 -L/usr/lib64 -lQt5Widgets -lQt5Core
//
#include "QtWidgets/QApplication"
#include "QtCore/QProcess"
int main(int argc, char* argv[])
{
QApplication app{argc, argv};
QProcess p;
QObject::connect(&p, &QProcess::readyReadStandardOutput, [&](){
printf("%s", p.readAllStandardOutput().constData());
});
p.start("xfreerdp", {"/u:user", "/p:123456", "/v:10.38.31.133", "/cert:tofu"});
app.exec();
return 0;
}
I am sorry I was mistaken not to post the minimal reproducible example at once. Maybe, I should close the question and create a new once, so that more people could see it?
In your program, QProcess will do like works as entered in the terminal this command :
For seeing the result better I checked open in Terminal in the Run section of Qt Creator:
So I do this in Qt and add some changes to your code:
#include "QtWidgets/QApplication"
#include "QtCore/QProcess"
int main(int argc, char *argv[])
{
QApplication app { argc, argv };
QProcess *p = new QProcess();
QStringList pArgs;
pArgs << "/u:user" << "/p:123456" << "/v:10.38.31.133" << "/cert:tofu";
p->setProgram(QString("xfreerdp"));
p->setArguments(pArgs);
p->start();
QObject::connect(p, &QProcess::readyReadStandardOutput, [&]()
{
// printf("%s", p->readAllStandardOutput().constData());
qDebug() << p->readAllStandardOutput().constData() << Qt::endl;
});
app.exec();
return 0;
}
you should take Arguments to QProcess by using QStringList.
As I test it takes 15 to 16 seconds delay to show you results but this is my results:

Why is the console asking for input even though there is no input in code?

I'm taking an online computer science class for grade 12 and we're using c++. I've never touched c++ and I'm starting to wish I never had. The teacher is comparing c++ to java (a language I can use perfectly fine) and we're currently learning how to input and output strings and chars. The simple practice problem was
Use one of fputc(), putc(), or putchar() to print your name one char at a time.
Since I have no clue how to use fputc() or putc() I decided to go with putchar()
#include <iostream>
using namespace std;
#include <stdio.h>
int main() {
cout << "My name is :" << endl;
putchar('J');
putchar('a');
putchar('c');
putchar('o');
putchar('b');
return 0;
}
I tried just using putchar(), and then added the cout, and have tried restarting eclipse, etc. but every time I run the program, the console asks for an input. There should not be an input for this program at all.
Try running your program from outside of the IDE and see what happens. When you launch a console program from inside of an IDE, a new console window is created to run the program in. When the program ends, the console window will close. Many IDEs setup the console to wait for you to press a key, giving you a chance to see the program's output, before the window closes.

QProcess that will outlive the parent for updating

There have been several posts regarding this, but I've not experienced the same. I'm running QT under Windows and trying to start an installer that will overwrite my app. I've been able to do this in C#, but being new to QT, I've not been able to find the "secret sauce" that allows the the launched process to outlive the app.
I've tried newing the process because someone mentioned that if they do that and don't delete the QProcess, then it was living on after the launcher app went away. I tried this, but as soon as my app quits, everything still goes away, albeit with a memory leak. I can't keep the app going because unlike Linux, Windows won't let you overwrite the application when it's running. Does anyone know how to do this?
What I need to do is really simple:
QString filename = ""full/path/to/installer.exe";
QProcess * pProcess = new QProcess();
int result = pProcess->startDetached(filename);
if (result)
QCoreApplication::quit();
else
QMessageBox::warning(this,tr("Oh NO!!"),tr("Couldn't start the installer!!!"),QMessageBox::Ok);
Actually, it works as described by OP.
This is my MCVE to demonstrate.
1) a child application testQProcessChild.cc:
#include <chrono>
#include <thread>
#include <iostream>
int main()
{
std::cout << "testQProcessChild started.\n"
<< "Sleeping for three seconds...\n";
std::this_thread::sleep_for(std::chrono::seconds(3));
std::cout << "testQProcessChild exits.\n";
return 0;
}
Compiled and tested:
$ g++ -std=c++11 -o testQProcessChild testQProcessChild.cc
$ ./testQProcessChild
testQProcessChild started.
Sleeping for three seconds...
testQProcessChild exits.
$
2) the Qt application testQProcessDetached.cc:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QProcess qProcess;
//qProcess.closeWriteChannel();
//qProcess.closeReadChannel(QProcess::StandardOutput);
//qProcess.closeReadChannel(QProcess::StandardError);
if (qProcess.startDetached(QString::fromLatin1("./testQProcessChild"))) {
qDebug() << "./testQProcessChild started.";
} else {
qDebug() << "Cannot start ./testQProcessChild!";
}
qDebug() << "testQProcessDetached exiting.";
return 0;
}
with project file testQProcessDetached.pro:
SOURCES = testQProcessDetached.cc
QT = widgets
Compiled and tested:
$ qmake-qt5 testQProcessDetached.pro
$ make
$ ./testQProcessDetached
testQProcessChild started.
Sleeping for three seconds...
./testQProcessChild started.
testQProcessDetached exiting.
$ testQProcessChild exits.
Please note, that testQProcessDetached exits which can be seen as the prompt $ appears again. Round about 3 seconds later the output testQProcessChild exits. appears (to prove that testQProcessChild outlives testQProcessDetached).
I suspected that channel connections could be an issue. Hence, after first successful attempt, I commented the close???Channel() calls and repeated the test – with the same result as before.
I've tested in cygwin64 on Windows 10.
The sample testQProcessDetached.cc modified to become a GUI application:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QPushButton qBtn(QString::fromUtf8("Start Child"));
qBtn.show();
QObject::connect(&qBtn, &QPushButton::clicked,
[&](bool) {
QProcess qProcess;
//qProcess.closeWriteChannel();
//qProcess.closeReadChannel(QProcess::StandardOutput);
//qProcess.closeReadChannel(QProcess::StandardError);
if (qProcess.startDetached(QString::fromLatin1("./testQProcessChild"))) {
qDebug() << "./testQProcessChild started.";
QApplication::quit();
} else {
qDebug() << "Cannot start ./testQProcessChild!";
}
});
return app.exec();
}
Compiled and tested:
$ qmake-qt5 testQProcessDetached.pro
$ make
$ ./testQProcessDetached
Click
testQProcessChild started.
Sleeping for three seconds...
./testQProcessChild started.
testQProcessDetached exiting.
$ testQProcessChild exits.
I compiled the second sample on VS2013 with Qt for Windows. It worked as well.
Thereby, I had to replace the relative path ./testQProcessChild with the absolute path (although both binaries resided in the same directory). As this is stated by OP as well, I didn't care about this.
A quick and dirty solution is to run your installer executable inside of a Windows command script and QProcess the command script. Then put a 3-5 second 'timeout' command at the start of the script to ensure that the original executable has finished.
It turns out that the method I posted does work, but it won't work if you run your app in the debugger. Apparently, as a safety precaution, the debugger closes all spawned threads/processes when the app terminates. Thank you all for your answers!!

c++ getchar works in vs 2010, doesn't in 2012

Why the program just exits, in vs 2012, while in 2010 does it wait for my input?
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string path = "c:\somepath";
cout << "Path is" + path << endl;
getchar();
return 0;
}
The getchar() function is not used in the program flow and only the side effect of waiting for input is used in your case. Instead of hacking your program to avoid closing the window you should use the proper way to keep it open.
Choose one of:
Command window
open a command prompt
navigate to the folder where you want your program to execute
type the path to the .exe and hit Enter. The command prompt is still open after execition of your program and there is not need for getchar().
Start without debugging
just use the menu item Debug->Start Without Debugging. The new console window is still open after execition of your program and there is not need for getchar().
Start with debugging
Set a breakpoint at the closing '}' of your main function.
use the menu item Debug->Start. The debugging session is still active and the window for your console program is still open. There is not need for getchar().
Why you should avoid getchar() to keep a window open?
It's a hack that depends on the program before. There can be some characters in the input buffer a s pointer out here: getchar() doesn't work well?
Your program can't be used in batch file if you come beyond the phase where you try to learn C or C++.
It's not necessary.

C++ , won't display last line of code

Shouldn't this work? I mean, the code is merely a test and is meant so that the dialogue goes this way : What is your name? name here, Hello name here, and yet it does not show the last line of Hello after I type in my name and click enter it just dissapears. Here is the code.
#include <iostream>
#include <string>
int main (void)
{
using std::cin;
using std::cout;
using std::string;
string name = "";
cout << "What is your name, pls?\n";
cin >> name;
cout << "\nHello " << name.c_str() << "\n";
return 0;
}
My guess is that you are running from the debugger, or double clicking the executable. In either of those cases, when the program ends, the console will close. So, the program produced output, but you just could not see it before the console closed.
Run the program from a pre-existing console so that the console remains after your program ends. Or, just whilst debugging, arrange that your program does not terminate immediately after emitting its final output. A simple way to do that is to place a break point at the end of the program.
It probably showed it right before it disappeared. If you're going to write console programs, and if you're going to send output to a console, you should run them from a console so the output has some place to go.
After you are done with your program, press Ctrl + F5 ( Run without debugging). This will prompt before closing the window and this is what you want.
Make sure you put a breakpoint before main goes out of scope. I guess your console disappears under VS?
Also, you don't need to extract the char* in the last cout statement:
cout << "\nHello " << name << endl;
Open a terminal (or a command prompt window).
Navigate to the folder that contains the executable.
Run it.
It's not disappearing. It is just running really fast.
Every IDE has a keyboard shortcut that allows you to run code and pause after the execution has finished.
This keyboard shortcut is Ctrl-F5 in Visual Studio.
I have no idea what IDE you're running, but that is your basic problem.
The other thing you can do is to test your code in ideone : ideone.com/hb4Cel (it's the same code. There is no point pasting it here)
A dirty workaround is to add something like this
cin >> name;
at the end, just before return 0;. It forces the window to wait for input (i.e. hitting return) before returning (which closes the program).
This isn't necessarily good design, but if all you want to do is run some tests then it'll do the trick.
Basically when you enter your name it displays your last line and exits after return 0.
Here are the following things to avoid that
1- use command line to run the application
Start->accessories->command prompt
Go to folder in which your application is using cd command
c:>cd c:\path\foldername
Now run the application by typing the program name e.g
c:\path\foldername>my_application.exe
It will display your last line.
2- Now if your are using microsoft visual c++ press ctrl+F5 to run your program
3- This is not recommended but you an use it as long as your are debugging then remove it from the code afterwards. Include conio.h header file and add getch(); line before return statement. It would hold the screen for you till you press a key.