Vectors

I have a program that I am supposes to convert from using a dynamic array to a vector. I am currently stuck on a function readData() where I need to read names into a c-string and scores into a vector. The instructor said that I shouldn't use the size variable from user input since a vector knows it's own size. So, I tried creating iterators to use as an end value in the for loop, but my code is not correct. Also, I tried using the insert()function to place scores into the vector and that is not working either. This is my first time working with these functions, so it looks like I am not seeing how to use them properly.

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  #include <iostream>
#include <vector>
using namespace std;

const int MAX_NAMESIZE = 24;

struct Highscore {
    char name[MAX_NAMESIZE];
    int score;
};
void getArraySize(int& size);
void readData(vector<Highscore>& myVec);
void sortData(vector<Highscore>& myVec);
void displayData(const vector<Highscore>& myVec);

int main()
{
    int size=0;

    getArraySize(size);
    vector<Highscore> myVec(size);

    readData(myVec);

    return 0;
}



void 
getArraySize(int& size) 
{
    cout << "How many scores will you enter?: ";
    cin >> size;
    cin.ignore();

}


void 
readData(vector<Highscore>& myVec)
{
    Highscore objectTo;
    vector<Highscore>::iterator start = myVec.begin();
    vector<Highscore>::iterator end = myVec.(end() - 1); // end() goes one index further which is NULL
                                                         // so end - 1 for last index.
    for (int index = 0; index < end; index++)
    {
        cout << "Enter the name for score #" << (index + 1) << ": ";
        cin >> objectTo.name[index];
       
        cout << "Enter the score for score #" << (index + 1) << ": ";
        myVec.insert(start, objectTo.score);
        start++;
    }
}
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <vector>

using namespace std;

const int MAX_NAMESIZE = 24;

struct Highscore {
    char name[MAX_NAMESIZE];
    int score;
};

void getArraySize(int& size);

void readData(vector<Highscore>& myVec);
void sortData(vector<Highscore>& myVec);
void displayData(const vector<Highscore>& myVec);

int main()
{
    int size=0;
    
    getArraySize(size);
    
    vector<Highscore> myVec;// (size);
    
    for (int i = 0; i < size; i++)
    {
        readData(myVec);
    }
    displayData(myVec);
    
    return 0;
}



void
getArraySize(int& size)
{
    cout << "How many scores will you enter?: ";
    cin >> size;
    // cin.ignore();
}


void readData(vector<Highscore>& myVec)
{
    Highscore objectTo;
    //
    //    vector<Highscore>::iterator start = myVec.begin();
    //    vector<Highscore>::iterator end = myVec.end() - 1); //<--
    // so end - 1 for last index.
    
    //    for (int index = 0; index < end; index++)
    //    {
    cout << "Enter the name for score # : "; // << (index + 1) << ": ";
    cin >> objectTo.name;//[index];
    
    cout << "Enter the score for score # : "; // << (index + 1) << ": ";
    cin >> objectTo.score;
    
    myVec.push_back(objectTo); // start, objectTo.score);
    //        start++;
    //    }
}

void displayData(const vector<Highscore>& myVec)
{
    for(auto i: myVec)
        std::cout << i.name << ' ' << i.score << '\n';
}


How many scores will you enter?: 3
Enter the name for score # : AA
Enter the score for score # : 1
Enter the name for score # : BB
Enter the score for score # : 2
Enter the name for score # : CC
Enter the score for score # : 3
AA 1
BB 2
CC 3
Program ended with exit code: 0
That looks way more simple than what I was trying to do!

If I wanted to use a loop in the readData() function, how would that work. Was I on the right track or was I way off?
I am still new in communicating data between objects in classes. In trying to understand: how does push_back(objectTo) work here? Does that mean one name as a c-string and one score as an int are being sent as arguments? I have only seen and int work on a vector, and this is my first time seeing an object.
This is what I tried in creating a for loop in the readData() function. I'm guessing that the vector needs to be pushed back somehow before using it as a condition, but not sure if i'm right or how to do it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void 
readData(vector<Highscore>& myVec)
{
    Highscore objectTo;
   
    for (auto it = begin(myVec); it != end(myVec); ++it) {

        cout << "Enter the name for score # ";
        cin >> objectTo.name;
    
        cout << "Enter the score for score #";
        cin >> objectTo.score;

        myVec.push_back(objectTo);
    }
}
That looks way more simple than what I was trying to do!

I'm glad you find it simpler. Make sure it is doing what you want - more or less. You'll still need ignore() etc if you put in names with spaces like Betty Boop instead of Betty. Leave that though for another time.

If I wanted to use a loop in the readData() function, how would that work.
Try it! You won't break anything. You can have a loop inside, or outside as I have done - think it through.

Was I on the right track or was I way off?
You decide. I left the commented out lines in the interests of your self-assessment.

I have only seen and int work on a vector, and this is my first time seeing an object.
<vectors> declared for a particular type can store objects/structs. Try it!

The struct or class wraps name and score into one object, a Highscore object, and that Highscore can be stored in a vector
of Highscore objects. (Beware though: It is often a poor design move to include the vector of Highscore's in the Highscore class, the vector stands alone or is part of a Highscore_List)

Just a friendly tip:
Ask questions as you see fit but don't rely on forums as a substitute for learning from using reputable tutorials and reference material as on this site :)

e.g. http://www.cplusplus.com/reference/vector/vector/push_back/
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <vector>
#include <iomanip>

const int MAX_NAMESIZE = 24;

struct Highscore {

    char name[MAX_NAMESIZE];
    int score;
};

// read data into each Hisgscore object that is present in MyVec
void readData( std::vector<Highscore>& myVec ) {

    std::cout << "enter data for " << myVec.size() << " scores\n" ;

    // for each Highscore in myVec
    // range based for: http://www.stroustrup.com/C++11FAQ.html#for
    for( Highscore& hs : myVec ) {

        std::cout << "name (no spaces, max " << MAX_NAMESIZE-1 << " chars): " ;
        // limit the number of chars to prevent a possible buffer overflow
        // std::setw: https://en.cppreference.com/w/cpp/io/manip/setw
        std::cin >> std::setw(MAX_NAMESIZE) >> hs.name ;

        std::cin.ignore( 1000, '\n' ) ; // extract and discard extra chars, if any

        std::cout << "score: " ;
        std::cin >> hs.score ;
        // this may need validation;
        // for example what do we do if the user enters a negative value?
    }
}

int main() {

    std::size_t sz = 0 ;
    std::cout << "How many scores will you enter? " ;
    std::cin >> sz ;

    if( sz > 0 ) {

        // create a vector that holds objects
        std::vector<Highscore> vec(sz) ;

        // read data into the sz objects in the vector
        readData(vec) ;

        // displayData
        for( const Highscore& hs : vec ) {

            std::cout << std::setw(MAX_NAMESIZE) << hs.name
                      << std::setw(8) << hs.score << '\n' ;
        }
    }

}
In trying to understand: how does push_back(objectTo) work here? Does that mean one name as a c-string and one score as an int are being sent as arguments? I have only seen and int work on a vector, and this is my first time seeing an object.
1
2
3
4
5
6
7
8
9
Highscore objectTo;
std::vector<Highscore> vec;

Highscore sample = objectTo;
vec.push_back( objectTo );

// sample is a Highscore object
// vec[0] is a Highscore object
// both are copies of objectTo 

How does Highscore sample = objectTo; work? The push_back uses that too.
So the way I am seeing this: Highscore objectTo is a variable that will hold any data that is stored as a Highscore. Then, when objectTo is placed inside push_back() the function automatically knows how to process the correct data from it according to the context at hand. Is this correct?
Yes, that's correct. The vector knows it is supposed to store Highscore objects because that's what you've told it to do with <Highscore> in the vector declaration.

Convince yourself ... add these lines to readData
1
2
3
// TRY AN int ...
    int n = 7;
    myVec.push_back(n);


You'll get an error message because an int is not the same type as a Highscore.
Last edited on
That is making sense. I just need to get used to it in practice. There seems to be so many ways that data can communicate in C++.

I got a for loop working in readData() now too using the begin() and end() functions as conditions. I have all the functions done now except sortData() which will probably be the hardest.

Thanks to everyone for the insight!
Sorting objects in a vector is 'easier' than you might think. Not completely easy though because you have to specify in your program how
The elements are compared using operator< for the first version, and comp for the second.
See the example in the tutorial,

http://www.cplusplus.com/reference/algorithm/sort/
That is the recommended way to sort. However,
I have a program that I am supposes to convert

If there is (working) self-written code that sorts, and real task is to look at similarities/differences of array and vector usage, then std::sort is moot.

One can sort dynamic array with std::sort as easy as vector.
Good to hear the feedback on what to expect in sorting with vectors. I will definitely look over the link.

That is exactly right keskiverto. I am given code that is written with a selection sort algorithm in descending order, and it has an additional function call within it which finds the largest index. Perhaps the instructor should have given a more detailed function name.

He recommeds trying to call sort() just so we know how to do it, but for the assignment, we have to convert the given algorithm without calling sort().
"function that finds the largest index"

Doesn't that mean "function that finds the index of the element that has largest value"?
(With N elements, no valid index is larger than N-1, but largest element could be at any index.)

Standard library has a function for that too:
http://www.cplusplus.com/reference/algorithm/max_element/
Like most algorithms, it is generic; can be used with array and vector (and most other containers).

Well, max_element() returns an "iterator", not "index". However, std::distance can compute index from iterator:
http://www.cplusplus.com/reference/iterator/distance/
I got the program finished.

Thanks to everyone for your help and pointing out links to read over!
Topic archived. No new replies allowed.