1

I'm trying to use displayVectorVer2() to have it only display the first 10 elements, but I don't know how to do it with iterators. I did try a few dumb things just to see what would happen: I compared the iterator to displayLimit in my for loop. I played around by subtracting vobj.end()-5 since my professor is only having me use 15 elements, but I fully well knew this was not a good idea.

#include <iostream>
#include <vector>
#include <ctime>

template <class T>
void fillVector(std::vector<T>& vobj, int n);

template <class T>
void displayVectorVer2(std::vector<T>& vobj, typename std::vector<T>::iterator ptr);

template <class T>
void fillVector(std::vector<T>& vobj, int n)
{
    srand((unsigned int)time(NULL));
    for (int i=0; i<n; ++i)
    {
        vobj.push_back(rand()%99999+1);
    }
}

template <class T>
void displayVectorVer2(std::vector<T>& vobj, typename std::vector<T>::iterator ptr)
{
    std::cout << "Vector object contains " << vobj.size() << " values which are" << std::endl;

    const unsigned displayLimit = 10;
    if (vobj.size()>displayLimit)
    {
        for (ptr=vobj.begin(); ptr<vobj.end(); ++ptr)
        {
            std::cout << "  " << *ptr;
        }
        std::cout << "  ..." << std::endl;
    }
    else
    {
        for (ptr=vobj.begin(); ptr<vobj.end(); ++ptr)
        {
            std::cout << "  " << *ptr;
        }
        std::cout << std::endl;
    }
}

int main()
{
    std::vector<int> vobj;
    std::cout << "Before calling fillVector(...): vobj contains " 
              << vobj.size() << " values." << std::endl;

    std::cout << "\nEnter # of random values you'd like to store in vobj: ";
    int n;
    std::cin >> n;

    std::cout << "\n*** Calling fillVector(...) ***" << std::endl;
    fillVector(vobj, n);

    std::cout << "\n*** Calling displayVectorVer2(...) ***" << std::endl;
    std::vector<int>::iterator ptr;
    displayVectorVer2(vobj,ptr);
}
S. Coughing
  • 176
  • 1
  • 11
  • There are many ways. Would you rather count up or down as you display? Would it benefit you to know your ending iterator ahead of time? Vectors are guaranteed to store elements in order in contiguous memory giving you some extra niceties when performing certain operations over their iterators compared to say a queue. – Abel Apr 11 '20 at 01:28
  • _"how to do it with iterators"_ -- why this artificial restriction? Also, what exactly is "it"? Are you just required to use iterators to step through the vector, or are you prohibited from having non-iterator variables, such as a variable that counts how many entries have been displayed so far? (Or something else? I do not intend to set up a false dichotomy.) – JaMiT Apr 11 '20 at 02:16
  • @JaMiT yes, i'm required to use iterators for that function; i don't think there's a prohibition on a variable that would do that – S. Coughing Apr 11 '20 at 02:24

1 Answers1

1

Maybe I am thinking too simple but, that wold solve your question:

I'm trying to use displayVectorVer2() to have it only display the first 10 elements

without knowing your full exercise, that would be my answer:

...
    const unsigned displayLimit = 10;
    if (vobj.size()>displayLimit)
    {
        for (ptr=vobj.begin(); ptr<vobj.begin()+displayLimit; ++ptr) 
        {
            std::cout << "  " << *ptr;
        }
        std::cout << "  ..." << std::endl;
    }
    else
...

edit:

That worked, but why does it work? I remember adding to vobj.begin() and getting extra empty elements appended to the original vector.

Not sure what exactly you did but maybe that helps you understanding your code:

...
   const unsigned displayLimit = 10;
    if (vobj.size()>displayLimit)
    {
        //Init ptr outside the for loop
        ptr = vobj.begin();

        //What the for loop is seeing with a more familiar syntax: 
        //for( ; i < 0 +displayLimit; ++i)
        //what you are seeing
        for (/*ptr init*/; ptr < vobj.begin() +displayLimit; ++ptr)
        {
            std::cout << "  " << *ptr;
        }
        std::cout << "  ..." << std::endl;
    }
...

The iterators just gives you the int value and you can use it with what ever "eats" int values. In your case the for loop.

If you tell the program to use an iterator you tell the program: "Just give me the number the Vector begins with and add 10".

In your case 0 "...and add 10"

You could also write a code like that with n passed to the function for being able to use .end - input + 10 for showing 10 lines:

...
template <class T>
void displayVectorVer2(std::vector<T>& vobj, typename std::vector<T>::iterator ptr,int n)
{
    std::cout << "Vector object contains " << vobj.size() << " values which are" << std::endl;

    const unsigned displayLimit = 10;
    if (vobj.size()>displayLimit)
    {
       ptr=vobj.begin();
        for (; ptr<vobj.end() -n +displayLimit; ++ptr)
        {
            std::cout << "  " << *ptr;
        }
        std::cout << "  ..." << std::endl;
    }
    else
    {
        for (ptr=vobj.begin(); ptr<vobj.end(); ++ptr)
        {
            std::cout << "  " << *ptr;
        }
        std::cout << std::endl;
    }
}

int main()
{
    std::vector<int> vobj;
    std::cout << "Before calling fillVector(...): vobj contains "
              << vobj.size() << " values." << std::endl;

    std::cout << "\nEnter # of random values you'd like to store in vobj: ";
    int n;
    std::cin >> n;

    std::cout << "\n*** Calling fillVector(...) ***" << std::endl;
    fillVector(vobj, n);

    std::cout << "\n*** Calling displayVectorVer2(...) ***" << std::endl;
    std::vector<int>::iterator ptr;
    displayVectorVer2(vobj,ptr,n);
}
...

You also shouldn't use srand in modern code anymore since it is depricated for more than 10 years since c++11 introduced <random> and srand can harm your program f.e. if used for generating seeds for sensitive code. Also srand provides not the "randomness" it should provide, srand generates some numbers more often than others - that's not random.

Ingo Mi
  • 999
  • 12
  • 26
  • 1
    That worked, but why does it work? I remember adding to `vobj.begin()` and getting extra empty elements appended to the original vector. – S. Coughing Apr 11 '20 at 03:45
  • @S.Coughing I added some more deep explaination to the code – Ingo Mi Apr 11 '20 at 04:21
  • 1
    that was helpful; i did a lot of digging on the random number generation and realized there was a `` library i was unsure if it was something i should consider; but, now since u mentioned it in this answer: i'll take a deeper look as i understood from other previous stackoverflow answers, the randomness as u stated isn't really random-- one more question: what do u mean by slope? or is that a typo? – S. Coughing Apr 11 '20 at 05:06
  • @S.Coughing Great to hear! :) Slope is a typo, means the same in my native language, I ment a loop, sry for that. I correct it. – Ingo Mi Apr 11 '20 at 08:54
  • is not that difficult besides that big selection of engines and distributions. You just need a random engine and a random distribution. The syntax is pretty much the same as for srand. // uniformly distributed from 0 to 6 inclusive uniform_int_distribution u (0, 6); default_random_engine e; // generates unsigned random integers Also shuffle and stuff works in the same manor. I also red in some security forums that srand has some vulnerabilities. – Ingo Mi Apr 11 '20 at 09:02
  • @S.Coughing I just posted a working example as answer to another question of yours. I quess that will help you. I Actually like your attitude on how you work through c++ and since I am still learning deeper concepts of c++ maybe you are open to figure out c++ stuff together, feel free to join me in telegram with https://t.me/CppQtStudy – Ingo Mi Apr 11 '20 at 09:36