masoud
masoud

Reputation: 56509

Passing argument string which contains spaces and quotes

Using QProcess::startDetached, I need to pass a dynamic argument list which is coming from another process to the starting process.

const QString & prog, const QStringList & args, const QString & workingDirectory ...)

Note that arguments that contain spaces are not passed to the process as separate arguments.

...

Windows: Arguments that contain spaces are wrapped in quotes. The started process will run as a regular standalone process.

I have a string which contains below text, It comes from an external program without any control on it:

-c "resume" -c "print 'Hi!'" -c "print 'Hello World'"

I need to pass above string to QProcess::startDetached so that the starting program catches it as same as above string.

Do I have to parse the string and build a string-list? Or anyone has a better solution?

Upvotes: 1

Views: 2201

Answers (2)

TheDarkKnight
TheDarkKnight

Reputation: 27621

You don't have to use a QStringList at all for the arguments, as there is this overloaded function: -

bool QProcess::startDetached(const QString & program)

Which, as the documentation states: -

Starts the program program in a new process. program is a single string of text containing both the program name and its arguments. The arguments are separated by one or more spaces.

The program string can also contain quotes, to ensure that arguments containing spaces are correctly supplied to the new process.

You may need to replace " with \", but you can do that from a QString

 

You can use parseCombinedArgString (from Qt's source code) to parse:

QStringList parseCombinedArgString(const QString &program)
{
    QStringList args;
    QString tmp;
    int quoteCount = 0;
    bool inQuote = false;
    // handle quoting. tokens can be surrounded by double quotes
    // "hello world". three consecutive double quotes represent
    // the quote character itself.
    for (int i = 0; i < program.size(); ++i)
    {
        if (program.at(i) == QLatin1Char('"'))
        {
            ++quoteCount;
            if (quoteCount == 3)
            {
                // third consecutive quote
                quoteCount = 0;
                tmp += program.at(i);
            }
            continue;
        }
        if (quoteCount)
        {
            if (quoteCount == 1)
                inQuote = !inQuote;
            quoteCount = 0;
        }
        if (!inQuote && program.at(i).isSpace())
        {
            if (!tmp.isEmpty())
            {
                args += tmp;
                tmp.clear();
            }
        }
        else
        {
            tmp += program.at(i);
        }
    }
    if (!tmp.isEmpty())
        args += tmp;
    return args;
}

Upvotes: 2

Some programmer dude
Some programmer dude

Reputation: 409356

Yes you have to "parse" the string, splitting it at the correct positions, and enter each sub-string into the QStringList object you pass to the function.

Upvotes: 1

Related Questions