Show a specific number of string at a time

Say that you have 15 strings but you only want to output 5 at a time and after each 5 you let the user press a key to show five more. How would you do that? Here is an output example.


Hello
My 
World
I
am
Show five more?(y/n)
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;

int main()
{
   char ans;
   string value;
   string line = "It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness,";
   vector<string> words;
   stringstream ss( line );
   while ( ss >> value ) words.push_back( value );


   for ( int i = 1; i <= words.size(); i++ )
   {
      cout << words[i-1] << endl;                // watch out for array index
      if ( i%5 == 0 && i != words.size() )       // every 5, give the opportunity to break out of the loop
      {
         cout << "Show 5 more? (y/n)";
         cin >> ans;
         if ( ans != 'y' ) break;                // may want to consider alternative responses
      }
   }
}
@lastchance pretty much nailed it. Don't see why you haven't marked this answer as complete, unless there's something else you're confused with.

-VX
Say that I have vector of structs, with friends would something like this work then?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void coutlist((vector<Person> friends)
{
   char ans;
   string value;
   stringstream ss( friends );
   while ( ss >> value ) friends.push_back( value );

   for(auto& e : friends)
    {
        cout << right << setw(20) << e.firstname;
        cout << setw(20) << e.lastname << endl;

      if ( i%5 == 0 && i != friends.size() )       // every 5, give the opportunity to break out of the loop
      {
         cout << "Show 5 more? (y/n)";
         cin >> ans;
         if ( ans != 'y' ) break;                // may want to consider alternative responses
      }
   }
}
Hello Markusfurst

If you already have content in your friend structure you certainly don't need to put any more in with stringstream (which I doubt you can do anyway). I only used stringstream as a quick way of creating some strings for an example.

Your for () loop won't work with auto & e because it doesn't know what i is. If you insist on using auto rather than a counter then you will have to increment i deliberately within the loop (having set it to 0 before looping). You will also have to test for your last element, unless you want a redundant prompt at the end.
@lastchance So I can remove this?
1
2
3
string value;
stringstream ss( friends );
while ( ss >> value ) friends.push_back( value );


This feels better, am I on the right track?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
char ans;
int counter=0;
    
for(auto& e : friends)
{
    counter++;
}

for( int i = 0; i <= counter; i++ )
    {
        cout << right << setw(20) << e.firstname;
        cout << setw(20) << e.lastname << endl;

      if ( i%5 == 0 && i != counter )       // every 5, give the opportunity to break out of the loop
      {
         cout << "Show 5 more? (y/n)";
         cin >> ans;
         if ( ans != 'y' ) break;                // may want to consider alternative responses
      }
   }
    
Last edited on
void coutlist((vector<Person> friends)
This will create an entirely new copy of the vector. It would be better to pass the existing vector by const reference:
void coutlist((cont vector<Person> &friends)

The problem you seem to be having is that you want to use a range-based for loop, but in lastchance's solution, you have to know if you're at the end of the input. The way to get around this is to ask if they want to see 5 more when you know that you already have one to display and to ask before displaying it, not after.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;

int
main()
{
    char ans;
    string value;
    string line = "It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness,";

    vector<string> words;
    stringstream ss( line );
    while ( ss >> value ) words.push_back( value );


    int i=5;
    for (string & word : words) {
        if (i-- == 0) {
            i = 4;
            cout << "Show 5 more? (y/n)";
            cin >> ans;
            if (ans != 'y') {
                break;
            }
        }
        cout << word << '\n';
    }
}

Note that inside the loop I had to reset the counter to 4, not 5.

Also note that I'm just using a counter rather than %, which is slower. Most of the time this won't matter.
Dosen't work with your method either.
@markusfurst: could you post your code, please. Complete, compilable version.
It works with your code @lastchance, I just looked at it the wrong way, sorry for that!
Well, I'm glad that you got it to work, @markusfurst.

It would be worth having a go to make it work with @dhayden's method as well, because that does two important things:
- it deals with the end of the more modern range-based for() loop;
- it uses a subset counter (actually, count-down); in itself, I don't think the % operation would take much time compared with writing to screen; however, a subset counter would be especially useful if, in the future, you decided to ask for "how many more to show", rather than the simple "y/n".
Thanks lastchance.

Markusfurst, what was wrong with my version? I tested it and thought that it was working correctly.
Topic archived. No new replies allowed.