Re: help a newbie with vectors

From: Matt Bitten (mbitten73_at_yahoo.com)
Date: 03/09/05


Date: 9 Mar 2005 10:39:47 -0800

Kamran wrote:
> I am a newbie in C++ and having a lot of problems with vectors.

I usually prefer the approach of earlier posters: lead someone
to an answer. But I feel like just giving answers away today.
So here is a general critique of your code:

vector<string>::iterator index;
index = channels.begin();
while(index != channels.end()) {
    // Loop body here
    ++index;
}

There is nothing wrong with the above loop, but it really is a "for"
loop in disguise. Why not write it as one? You can also put the
iterator inside the scope of the loop, to avoid name conflicts with
other variables. Lastly, since you are not using the iterator to
modify the container, make it a const_iterator:

for(vector<string>::const_iterator index = channels.begin();
    index != channels.end();
    ++index) {
    // Loop body here
}

Second, converting your string literal to a string object and then
back to a (char *) is a bit odd. Leave off the ".c_str()".

Now for the actual errors. You are using "find" incorrectly. It
takes a range and a value. It finds the first occurrence of the
value in the range, and returns an iterator to it. Or it returns
the end of the range if nothing was found.

You are doing multiple finds on nearly the same range, so of course
you find the same thing over and over again. And when your range
shrinks enough that the item is not found, find returns .end().
This means "not found", but you are interpreting it as a successful
find beyond the end of the list.

Instead, do your first find starting at the beginning. Then do
your next find starting at the position after the result of the
previous find. And so on. Stop when find returns channels.end().
Like this:

vector<string>::const_iterator finditer = channels.begin();
while(true) {
    finditer = find(finditer, channels.end(), string("SPB2_BHZ"));
    if(finditer == channels.end()) break; // Not found
    size_t pos = finditer - channels.begin();
    cout << "pos: " << pos << endl;
    indices[ncopy++] = pos;
    ++finditer; // Next find starts just after result of this one
}

One more minor note: It can be inefficient to call the .end()
member function over and over. This varies by container, and for
a vector it is hardly an issue. However, it is not a bad idea
to get in the habit of doing things like this:

vector<string>::const_iterator finditer = channels.begin();
const vector<string>::const_iterator endmark = channels.end();
while(true) {
    finditer = find(finditer, endmark, string("SPB2_BHZ"));
    if(finditer == endmark) break; // Not found
    size_t pos = finditer - channels.begin();
    cout << "pos: " << pos << endl;
    indices[ncopy++] = pos;
    ++finditer; // Next find starts just after result of this one
}

And of course you can convert that to a "for" loop, if you want.



Relevant Pages

  • Re: STL Vector: Unexpected behavior
    ... iterator of that container. ... you could move all pointers you want to keep to a new ... you also omit checking if the pointer is zero in your loop. ...
    (microsoft.public.vc.stl)
  • Re: Factoring iteration
    ... Now it's cool that the double-nested loop turns into just the one line ... grid iterator class, where the actual per-item action is a method, ... All masks with only one bit set represent a solution for that field. ... actually requires backtracking, unless you want to find all possible ...
    (comp.lang.forth)
  • Re: std::vector : begin, end and insert - Using Objects instead of ints
    ... When there's a choice, prefer preincrement to postincrement, because pre ... The thing is, efficiency can be measured objectively, while "readability" ... split the operation into two statements, e.g. when erasing a list iterator. ... certain kind of loop that omits stmt3 in a for-loop header when you decide ...
    (microsoft.public.vc.mfc)
  • Re: Ada Popularity: Comparison of Ada/Charles with C++ STL (and Perl)
    ... > while Has_Element loop ... > container, the passive iterator is preferred: ... > If you have an array type, then you can give it a container-like ...
    (comp.lang.ada)
  • Re: Generics and for each
    ... so the compiler has no way of matching the 'String' type of the loop ... I used 'String' to ... stands it fails because it doesn't know that the Iterator is a ...
    (comp.lang.java.programmer)