PDA

View Full Version : C++/Qt5 - Adding quotes " into a QString



jimbo
6th January 2016, 20:01
Qt5.5.1
QtCreator 3.5.1
Windows 7

Hello,

I'm trying to build a QString for a QProcess command.
I'm getting stray '\' (back slashes) in my output where I try to insert a ".
It appears that I need the " in 'cmd' as there are spaces in the path and file names.
I can't work out how to remove the '\' from the 'cmd' QString (I've tried various variations)
or not to get them there in the first place.
I think its something to do with 'escaping' but not sure what or how.
Help would be appriciated.

Regards

QString cmd = ("7z x -y ");
cmd.append(fileinfo.fileName());
cmd.append(" *.* ");
cmd.append("-o");

cmd.append('"'); //QString output = "Hello \"world\"!"; //string literal - works

cmd.append(destination);
cmd.append("/Files to copy");

cmd.append('"');

cmd.append(" -r");
qDebug() << cmd;

qDebug output:-
"7z x -y myFile.zip *.* -o\"H:/my dir/systems/output files\" -r"
^ ^

Terminal commmand, works ok.
7z x -y myFile.zip *.* -o"H:/my dir/systems/output files" -r

anda_skoa
6th January 2016, 20:13
You are trying to create a command string that contains the command and its arguments.

But QProcess takes the command without arguments and lets you pass the arguments using a QStringList and takes care of escaping for you.

Cheers,
_

jimbo
6th January 2016, 20:49
Hello anda_skoda,

I use a similar format elsewhere and it works, difference being no quotes in the command.

cmd1 = "7z";
cmd1.append(" e -bsp2 ").append(fileinfo.fileName());

qDebug() << "cmd1 - " << cmd1;
cmd1 - "7z e -bsp2 myFile.zip"However, I'll have a play with QStringList.

Regards

anda_skoa
6th January 2016, 21:00
While manual escaping may work, it is just unnecessary complexity.

Cheers,
_

jimbo
7th January 2016, 12:15
Hello anda_skoda,

I think maybe there is a little confusion from my previous posts.

QStringList arguments;
QString cmd = ("7z");
arguments << " x " << "-y" << " *.* " << "-o" << (destination + "/output files") << " -r";
qDebug() << "Cmd - " << cmd;
qDebug() << "Arg - " << (arguments.join(""));

Cmd - "7z"
Arg - " x -y *.* -oH:/my dir/systems/output files -r"
process->start(cmd, arguments);

Arg has to look like:-
" x -y *.* -o"H:/my dir/systems/output files" -r"
^ ^Note - the extra 'quotes', these are needed by the program I'm calling.

This is the terminal commmand that works ok.
7z x -y myFile.zip *.* -o"H:/my dir/systems/output files" -r
^ ^
What I can't work out is how to add the quotes to the arguments list.

Regards

yeye_olive
7th January 2016, 12:41
Arg has to look like:-
" x -y *.* -o"H:/my dir/systems/output files" -r"
^ ^[/code]Note - the extra 'quotes', these are needed by the program I'm calling.

This is the terminal commmand that works ok.
7z x -y myFile.zip *.* -o"H:/my dir/systems/output files" -r
^ ^
If this is a command you type in a terminal, then it is interpreted by the shell, which means that those quotes are probably only there to yield a single argument -oH:/my dir/systems/output files.

anda_skoa
7th January 2016, 12:43
Why did you put spaces into the arguments?

" x " is going to end up as " x ", are you sure 7z is still capable of understanding that as x?

Cheers,
_

ChrisW67
7th January 2016, 21:59
Similar problem with " *.* " and " -r".

jimbo
11th January 2016, 18:36
Helllo,

Sorry for the delay in replying.
Thanks to all who have responded.

I think the problem with the quotes being needed is that Windows allows paths and filenames with spaces,
and from what I've read it seems that if there are spaces the string needs to be in enclosed quotes.
I think the program I'm calling requires them for this reason or maybe needs them for its own syntax handling.
I cleaned the spaces in the args, no help.

Regards

anda_skoa
11th January 2016, 19:17
Maybe "*.*" is not interpreted by the program but by the shell?

Have you tried calling a simple test program instead of 7z and see how it receives the arguments?
I.e. to determine if the path is passed as several arguments?
Because spaces in file names is expected (on all platforms), the argument quoting should take care of that.

Cheers,
_

jimbo
12th January 2016, 13:25
Hello anda_skoa,

I've found a solution (sort of) by using relative paths (now quotes not needed).
The only thing is, I can't have any spaces in the QString 'NewDir'.
The spaces in the args are needed.
Thanks for your help.

Regards


process->start(QString("%1%2%3%4%5%6").arg("7z x -y ",
fileinfo.fileName(),
" *.*",
" -o",
newDir,
" -r"));

anda_skoa
12th January 2016, 14:02
Since you made no indication if you have actually tested the quoting, I assume you did not.

The arguments are passed, with spaces and all, as-is to the called program as far as I can tell (Qt 5.5.1, Linux)


#include <QtCore>

#include <iostream>

using namespace std;

int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);

QStringList args = app.arguments();

// if called with args, just write them to stdout, one per line
if (args.count() > 1) {
args.takeFirst(); // remove the program itself
foreach (const QString &arg, args) {
std::cout << qPrintable(arg) << std::endl;
}
return 0;
}

args.clear();

// otherwise start ourselves with the test arguments
args << "1" << " 2 " << "3 4 5";

QProcess process;
process.start(app.applicationFilePath(), args),
process.waitForFinished(10000);

QByteArray data = process.readAllStandardOutput();
QTextStream stream(&data, QIODevice::ReadOnly);
int lineNumber = 0;
do {
const QString line = stream.readLine();
++lineNumber;
std::cout << lineNumber << ": '" << qPrintable(line) << "'" << std::endl;
} while (!stream.atEnd());

return 0;
}


Cheers,
_