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.
#include <iostream>
#include <vector>
usingnamespace std;
constint 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
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 :)
#include <iostream>
#include <vector>
#include <iomanip>
constint 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#forfor( 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.
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.
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().
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.)