user7344905
user7344905

Reputation: 27

c++ - How to extract first element out of a vector<string> and reduce the vector size by 1 in a loop

string line= "";
vector<string> tokens;
//populate the vector 'tokens'

//loop through vector 'tokens' until it becomes empty
{
    //extract out 'line' containing the first element of the vector.
    //reduce the size of 'tokens' by one through deleting the first element 
}
//use 'line' string one by one in the subsequent code 

Suppose 'tokens' is containing two elements, e.g.

cat, dog, bull

On the first iteration, I want to extract 'cat' out from the vector and reduce its size by 1. It will contain now:

dog, bull

Now, I want to use this extracted element 'cat' (stored in a string 'line') in my subsequent code out of the loop. Next time I want to pick 'dog' and make the vector contain only

bull

. And so on. Thanks in advance for your ideas!

Upvotes: 0

Views: 4696

Answers (4)

Jarod42
Jarod42

Reputation: 217398

The idiomatic way would be:

std::vector<std::string> tokens;
// populate the vector 'tokens'
// ...

for (const auto& token : tokens) {
    // use 'token' string one by one in the subsequent code, as:
    std::cout << token << std::endl;
}
tokens.clear(); // If needed.

Upvotes: 0

2785528
2785528

Reputation: 5566

The std::vector provides the operation you seem to desire at the other end ...

std::vector<std::string>  tokens;

// the last token can be accessed: 
std::string tok = tokens.back();

// removing the last tok
assert(tokens.size());  // pop_back on an empty vector is UB
tokens.pop_back();      // removes element from vector - constant time!

// and if you get confused on how to load tokens in reverse order
// you can load as planned, then reverse the elements to do your work
std::reverse(std::begin(tokens), std::end(tokens))

Give it a try. I found working at the back of the vector easy to adapt to.

Upvotes: 0

Fran&#231;ois Andrieux
Fran&#231;ois Andrieux

Reputation: 29022

When iterating over a container with the intention of emptying it, it's easier to simply iterate as long as the container is not empty.

#include <iostream>
#include <string>
#include <vector>

int main()
{
    std::vector<std::string> tokens = {"cat", "dog", "bull"};
    while(tokens.empty() == false)
    {
        // Extract the data from first element in the list
        auto line = std::move(tokens.front());

        // Pop the moved element from the vector
        tokens.erase(tokens.begin());

        // Do work with 'line'
        std::cout << line << '\n';
    }

    return 0;
}

That said, it's very inefficient to remove elements from the front of a vector, as all following elements have to be moved up. Consider removing elements from the back instead.

Upvotes: 3

Edward Strange
Edward Strange

Reputation: 40859

tokens.erase(tokens.begin());

That's how.

Upvotes: 0

Related Questions