0

I'm currently working on a small program where I will count the amount of times a certain word is mentioned in a text. But I only want to count for the word when the previous element is a 10 digit number. So what I'm trying is do is that I will check if the previous element of the iterator consist of a 10 digit number. But I don't know how to iterate to the previous element from the iterator.

QString input = ui->listinput->toPlainText();

QStringList inputlist = input.split(QRegExp("[\s\n\r " "]+"));

unsigned int boxCount(0);

for(QStringList::iterator it(inputlist.begin()); it != inputlist.end(); ++it){

    if(!QString::compare(*it,box)) ++boxCount;

}

So I want the if statement to be something like this:

if(!QString::compare(*it,box) && *prev_it == 10 digits) ++boxCount;

Any help will be appreciated. Thanks!

Mrchacha
  • 197
  • 1
  • 17
  • 1
    Might be simpler to just use index. Note that first string in the list does not have a previous, so you want to start your loop from 2nd item. – hyde Aug 18 '16 at 10:08
  • Btw if I see things the right way you are not changing the elements inside the list so as @hyde mentioned using index is a simple way and in addition to that using `at(...)` will be the right way to go since `at(...)` returns a `const` which can only be read (basically that's what you are doing here). Iterators allow both reading and writing. No need to expose something that is enough to be `readonly` to write access. – rbaleksandar Aug 18 '16 at 10:19
  • Also the advantage of iterating through a loop disappears in terms of boundary check if you manually tinker with it. I'm mentioning this because `at(...)` (which I have discovered only recently) doesn't check for out of bounds. – rbaleksandar Aug 18 '16 at 10:20
  • Ah, it seems that there is `constBegin()` and `constEnd()` for iterators in Qt to avoid changing the data the iterator points at. – rbaleksandar Aug 18 '16 at 10:38

1 Answers1

2

You can obtain the previous iterator by doing:

if (it != inputlist.begin()) {
    prev_it = it - 1
}

You will have to make an exception for the first element, since it has no previous element. Either check the range (like above) or start your for loop one element past the first (note the '+ 1'):

for (QStringList::iterator it(inputlist.begin() + 1); it != inputlist.end(); ++it) {
    ...
}

In the latter case, you must be sure that your list contains at least one element.

If you then want to check if the number is 10-digit (assuming decimal and integer) you can try the following:

bool ok = false;
long num = prev_it->toLong(&ok);
if (ok && num >= 1000000000) {
    // do something
}

Note: I used the long type because I do not know the range of your numbers, but they seemed big.

Peter K
  • 1,372
  • 8
  • 24
  • Don't forget to check the range first. – Simon Kraemer Aug 18 '16 at 10:14
  • You should check if `it-1` won't go one element lower. While the `for` loop makes sure you don't go out of bounds of the list changing the iterator inside needs the extra check. Otherwise we can do `it = it + 1000` followed by some action that takes the value of the iterator for a list of 10 items and hope for the application not to crash or create some sort of memory corruption issue that might actually remain invisible and cause a lot of headaches. – rbaleksandar Aug 18 '16 at 10:14
  • @SimonKraemer Added range check – Peter K Aug 18 '16 at 10:20
  • @rbaleksandar The word I'm searching for will never occur in the first string that shouldn't be any problem. But I still don't get how I can check if `--it==10 digits`. – Mrchacha Aug 18 '16 at 10:26
  • You need to dereference (by using the `*` operator) the decremented iterator. – rbaleksandar Aug 18 '16 at 10:29
  • @rbaleksandar I understand, but are there any function to check if the element is a 10 digits number? I found `isdigit()` function, but can't make it work. – Mrchacha Aug 18 '16 at 10:49
  • Added a way to check if the number is 10 digits. – Peter K Aug 18 '16 at 10:55
  • @PeterK Thank you so much! It works as expected now! :) – Mrchacha Aug 18 '16 at 11:03
  • You can also go the other way around by converting `100...0` to `QString` using `QString::number(...)` and comparing the `length()` return value for both the dereferenced iterator and the number. This has the advantage that you need not cast your dereferenced iterator to a number (in the answer above using `QString::toLong(...)`) so you can assign the `QString::number(10...0)` to a const and just reuse it over and over again. Of course with my solution you need an extra `QString` in your memory. – rbaleksandar Aug 18 '16 at 11:23
  • This assumes that everything is a number, which, as I understood, is not the case. If not everything is a number, using QString::toLong will verify that it actually is a number. – Peter K Aug 18 '16 at 11:25