QString remove last characters - qt

How to remove /Job from /home/admin/job0/Job
QString name = "/home/admin/job0/Job"
I want to remove last string after"/"

You have QString::chop() for the case when you already know how many characters to remove.
It is same as QString::remove(), just works from the back of string.

Find last slash with QString::lastIndexOf.
After that get substring with QString::left till the position of the last slash occurrence
QString name = "/home/admin/job0/Job";
int pos = name.lastIndexOf(QChar('/'));
qDebug() << name.left(pos);
This will print:
"/home/admin/job0"
You should check int pos for -1 to be sure the slash was found at all.
To include last slash in output add +1 to the founded position
qDebug() << name.left(pos+1);
Will output:
"/home/admin/job0/"

Maybe easiest to understand for later readers would probably be:
QString s("/home/admin/job0/Job");
s.truncate(s.lastIndexOf(QChar('/'));
qDebug() << s;
as the code literaly says what you intended.

You can do something like this:
QString s("/home/admin/job0/Job");
s.remove(QRegularExpression("\\/(?:.(?!\\/))+$"));
// s is "/home/admin/job0" now

If you are using Qt upper than 6 and sure that "/" constains in your word you should use QString::first(qsizetype n) const function instead QString::left(qsizetype n) const
Example:
QString url= "/home/admin/job0/Job"
QString result=url.first(lastIndexOf(QChar('/')));
If you run these code:
QElapsedTimer timer;
timer.start();
for (int j=0; j<10000000; j++)
{
QString name = "/home/admin/job0/Job";
int pos = name.lastIndexOf("/");
name.left(pos);
}
qDebug() << "left method" << timer.elapsed() << "milliseconds";
timer.start();
for (int j=0; j<10000000; j++)
{
QString name = "/home/admin/job0/Job";
int pos = name.lastIndexOf(QChar('/'));
name.first(pos);
}
qDebug() << "frist method" << timer.elapsed() << "milliseconds";
Results:
left method 10034 milliseconds
frist method 8098 milliseconds

sorry for replying to this post after 4 years, but I have (I think) the most efficient answer.
You can use
qstr.remove(0, 1); //removes the first character
qstr.remove(1, 1); //removes the last character
Thats everything you have to do, to delete characters ONE BY ONE (first or last) from a QString, until 1 character remains.

Related

QRegExp does not match even though regex101.com does

I need to extract some data from string with simple syntax. The syntax is this:
_IMPORT:[any text] - [HEX number] #[decimal number]
Therefore I created regex you can see below in the code:
//SYNTAX: _IMPORT:%1 - %2 #%3
static const QRegExp matchImportLink("^_IMPORT:(.*?) - ([A-Fa-f0-9]+) #([0-9]+)$");
QRegExp importLink(matchImportLink);
QString qtWtf(importLink.pattern());
const int index = importLink.indexIn(mappingName);
qDebug()<< "Input string: "<<mappingName;
qDebug()<< "Regular expression:"<<qtWtf;
qDebug()<< "Result: "<< index;
For some reason, that does not work, I get this output:
Input string: "_IMPORT:ddd - 92806f0f96a6dea91c37244128f7d00f #0"
Regular expression: "^_IMPORT:(.*?) - ([A-Fa-f0-9]+) #([0-9]+)$"
Result: -1
I even tried to remove the anchors ^ and $ but that didn't help and also is undesired. The annoying thing is that this regexp works perfectly if I copy the output in regex101.com, as you can see here: https://regex101.com/r/oT6cY3/1
Can anyone explain what is wrong here? Did I stumble upon Qt bug? I use Qt 5.6. Is there any workaround for this?
It seems like Qt does not recognize the quatifier *? as valid. Check the method QRegExp::isValid() againts your pattern. In my case it did not work because of this. And the documentation tells that any invalid pattern will never match.
So first thing I tried was skipping the ? which perfectly fits your provided string with all capturing groups. Here is my code.
QString str("_IMPORT:ddd - 92806f0f96a6dea91c37244128f7d00f #0");
QRegExp exp("^_IMPORT:(.*) - ([A-Fa-f0-9]+) #([0-9]+)$");
qDebug() << "pattern:" << exp.pattern();
qDebug() << "valid:" << exp.isValid();
int pos = 0;
while ((pos = exp.indexIn(str, pos)) != -1) {
for (int i = 1; i <= exp.captureCount(); ++i)
qDebug() << "pos:" << pos << "len:" << exp.matchedLength() << "val:" << exp.cap(i);
pos += exp.matchedLength();
}
And here is the resulting output.
pattern: "^_IMPORT:(.*) - ([A-Fa-f0-9]+) #([0-9]+)$"
valid: true
pos: 0 len: 49 val: "ddd"
pos: 0 len: 49 val: "92806f0f96a6dea91c37244128f7d00f"
pos: 0 len: 49 val: "0"
Tested using Qt 5.6.1.
Also note that you may set greedy evaluation using QRegExp::setMinimal(bool).

Do you lose the reserved space in a Qt string with the QString::clear() function?

I am working on a loop where I want to copy a few characters from a string to another. I know the limit is around 20 characters so I want to do this outside the loop:
QString name;
name.reserve(25);
That way I have a buffer ready to be filled and Qt avoids reallocating it every time a name is parsed. Only, to get the name I do something like this:
for(int i(0); i < 20 && *s != '\0'; ++i)
{
name += *s;
}
which means I have to reset the name each time. How can I do that and be sure that the reserved space doesn't get lost every time?
// will reserved memory be lost after this call?
name.clear();
// would that be more likely to keep the memory buffer?
name = "";
The documentation does not seem to say one way or the other.
The complete set of loops goes something like this:
QString name;
name.reserve(25);
for(QChar const *s(input.data()); *s != '\0'; ++s)
{
...snip...
if(<some condition>)
{
name.clear() // losing reserved data here?
for(int i(0); i < 20 && *s != '\0'; ++i)
{
name += *s;
}
...snip...
}
...snip...
}
Calling QString::clear() will cause your reserved space to be lost. Consider the following:
QString s;
s.reserve(25);
qDebug() << "Before Clear: " << s.capacity();
s.clear();
qDebug() << "After Clear: " << s.capacity();
Output:
Before Clear: 25
After Clear: 0
The most efficient way to remove the contents of the string without losing your reserved space is to call QString::resize():
QString s;
s.reserve(25);
qDebug() << "Before Resize: " << s.capacity();
s.resize(0);
qDebug() << "After Resize: " << s.capacity();
Output:
Before Resize: 25
After Resize: 25
In the implementation of QString::resize(), a call to resize(0) for strings with reserved capacity amounts to setting the internal size value to 0 and setting the first character of the internal buffer to '\0'.

QComboBox findText fails to find QString

Here is my code:
const QString k_NoFilter = "No Filter";
const QString k_Filter1 = "UV filter";
QStringList filters;
filters << k_NoFilter << k_Filter1;
ui.comboFilter->addItems(filters);
int ix = ui.comboFilter->findText(k_NoFilter);
ui.comboFilter->setCurrentIndex(ix);
I can't get the index. It always is -1. What might be wrong?
This is because the string for the item is stored by Qt in a weird way. It is ended with two white spaces (maybe '\r' and '\n').

Qt QVariant toList not working

I have a Qt (4.7) program that takes a QByteArray and should break it into a list of QVariants, after using a parser to transform it into a QVariant. The problems seem to arise when I try to use the toList() function. I have something similar to this:
QVariant var = //whatever the value passed in is...
std::cout << "Data = " << var.toString().toStdString() << std::endl;
QList<QVariant> varlist = var.toList();
std::cout << "List Size = " << varlist.size() << std::endl;
which would return this:
Data = variant1 variant2 variant3
Size = 0
where the size should clearly be 3. Does anyone have an idea what I may be doing wrong? thanks!
The documentation of toList() says:
Returns the variant as a QVariantList if the variant has userType() QMetaType::QVariantList or QMetaType::QStringList; otherwise returns an empty list.
My guess is, your variant's userType() is neither of those two.
You probably need to construct your variant differently, e.g.
QVariantList list;
list << variant1 << variant2 << variant3;
QVariant var = list;
So, I have no idea why, but when I put the command I specified above into a separate function, ie QList<QVariant> myClass::ToList(QVariant v){return v.toList();}, and then call varlist = myClass::ToList(v), it works. Still doesn't the original way, but this way it's fine. Guess I'll just chalk it up to one of the quirks of Qt...

quint16 on qbytearray

i need add on firt position of qbytearray a quint16 and after read it: How can i to do it?
I have try this:
quint16 pos = 0;
QFile file(m_pathFile);
if (file.open(QFile::ReadOnly))
{
qDebug() << "el fichero existe";
m_udpSocket->bind(m_port);
QByteArray datagram;
while (!file.atEnd())
{
datagram.begin();
datagram.append(pos++);
datagram = file.read(m_blockSize);
qDebug() << "Sec" << datagram.at(0);
}
}
Thanks you very much
I got add with:
datagram.begin();
datagram.setNum(pos, 10);
datagram.append(file.read(m_blockSize));
but i don't know as read it
Thanks
Ok, first of all, that datagram.begin() is useless since it returns an iterator that you don't assign at all. If you want to insert a number in the first position of a QByteArray you can do something like:
datagram.insert(0, QString::number(pos++));
To read it, the simplest way is to use a QTextStream like this:
QTextStream str(datagram);
quint16 num;
str >> num;
Also, take a look at the docs before posting, because the Qt ones are really simple and helpful if you know how to search (and it's not that difficult, trust me).

Resources