QStringList object unavalable in for loop
-
I'm attempting to make a fake **argv[] and argc set to use with Boost Program Options. A line is read from a script file, and I'm using Program Options to parse it. As it is now, I'm reading the line from file successfully into a QString, and I'm splitting into a QStringList, apparently also successfully. I then try to make a C-style char * array. After reading the second string into the array, the QStringList is shown as unavailable, and I SEGFAULT when trying to execute the third loop.
The line being read (AppName substituted):
AppName -b black -c white -t $''
My code:
//Simulate argv** and argc QStringList Qargv = line.split(' ', Qt::KeepEmptyParts); int fargc = Qargv.count(); // Fake argc char* fargv[fargc]; // Fake argv for (int j = 0; j < fargc; j++) strcpy(fargv[j], Qargv.at(j).toStdString().c_str());
I've also tried Qargv.at(j).toLocal8bit().constData() with the same results. I've also attempted to move the declaration of Qargv up a scope, copy the C-string to an intermediate char * variable before assignment, and copying to a std::string to convert to C-string. Some results have been interesting, but this is the most succinct and easy to describe. It always goes <not available> after copying "-b" into fargv[1].
-
You have not allocated memory to copy to the data at this address
Qargv.at(j).toStdString().c_str()
into. In your code eachfargv[j]
is uninitialized. Each fargv pointer should point to a block of memory that is large enough to hold the argument plus a\0
byte.Depending on the data lifetime requirements and whether Boost program options modifies the data (I suspect not), there is possibly a neater way to do this using a QByteArray. Load the line into a QByteArray, swap the spaces/delimiters for
\0
, and build fargv with pointers into that buffer. -
Thanks for the help. I haven't messed with memory allocation much, so I didn't think about it. The code has been adjusted.
//Simulate argv** and argc QStringList Qargv = line.split(' ', Qt::KeepEmptyParts); int fargc = Qargv.count(); // Fake argc char **fargv = new char*[fargc]; // Fake **argv. for (int j = 0; j < fargc; j++) fargv[j] = qstrdup(Qargv.at(j).toStdString().c_str());
It now does mostly what I want it to do. What I have to figure out now is how to break up that QStringList so that I can keep all parts within $' ... ' together.
-
Thanks for the help. I haven't messed with memory allocation much, so I didn't think about it. The code has been adjusted.
//Simulate argv** and argc QStringList Qargv = line.split(' ', Qt::KeepEmptyParts); int fargc = Qargv.count(); // Fake argc char **fargv = new char*[fargc]; // Fake **argv. for (int j = 0; j < fargc; j++) fargv[j] = qstrdup(Qargv.at(j).toStdString().c_str());
It now does mostly what I want it to do. What I have to figure out now is how to break up that QStringList so that I can keep all parts within $' ... ' together.
@rcx11 said in QStringList object unavalable in for loop:
I can keep all parts within $' ... ' together.
In that case splitting on space may not be what you intend. Show an example of what the complete string
line
looks like (I assume not just with the$''
empty at the end, else what is the problem?) and how you would want it to be split into separate arguments. -
I fiddled around and got it working.
QStringList preserveReminder; QStringList Qargv; if (line.contains("$\'")) { preserveReminder = line.split("$\'", Qt::SkipEmptyParts); // Split the reminder from the rest because I need to prserve it as a single string Qargv = preserveReminder.at(0).split(' ', Qt::SkipEmptyParts); // Split everything else into separate strings. Qargv.append("$\'" + preserveReminder.at(1)); // Add the second string back with a restored $' } else Qargv = line.split(' ', Qt::SkipEmptyParts);
The nature of what I'm writing, I don't have to worry about multiple $' .. .' segments.