I am trying to input data to an array and then print them by using a function but I am not sure how to organize the code.
#include <iostream>
using namespace std;
void showGrade(double grade[], int size);
int main()
{
double grade[];
int size;
for (int i = 0; i < size; i++)
{
cout << "Please enter the number of grade" << endl;
cin >> size;
}
showGrade(grade, size);
return 0;
}
void showGrade(double grade[], int size) //How many grade we have
{
for (int counter = 0; counter < size; counter++)
{
cout << "Please enter your grades: " << endl;
cin >> grade[counter];
cout << "Here are your grades: " << endl;
}
}
I Expect to see how many grades I input and then show them.
UPDATE 8/28/19
I figured out how to do it in main function successfully. But what I really want is to put them in a seperate function. My new codes have error at the function call which is type name is not allowed and expected a ')'. How do I make it work?
#include <iostream>
using namespace std;
void showGrades(double ar[], int size);
int main()
{
double ar[20];
int size;
showGrades(double ar[size], int size);
system("pause");
return 0;
}
void showGrades(double ar[], int size) {
cout << "Please enter the number of grade "; // array size
cin >> size;
cout << "Please enter your grades " << endl;
for (int i = 0; i < size; i++) {
cin >> ar[i];
}
cout << "The grades you entered are: " << endl;
for (int i = 0; i < size; i++) {
cout << ar[i] << endl;
}
}
First of all, you need to use the standard container
std::vector
instead of the double grade[];, since you want a variable-length
array as per user input.
Secondly, you are using un-initialized size variable in
for (int i = 0; i < size; i++)
hence it will be initialized with a garbage value. There you need no for-loop
A good starting would be:
#include <iostream>
#include <vector> // std::vector
void showGrade(std::vector<double>& grade)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -> pass the vector by ref, as the grades should be inseted to the it
{
// the logic
}
int main()
{
int size;
std::cout << "Please enter the number of grade" << endl;
std::cin >> size;
std::vector<double> grade;
grade.reserve(size); // reserve memory for unwanted re-allocations
showGrade(grade);
return 0;
}
I leave it to you to complete, after reading about the std::vector more.
Also, do not practice with using namespace std;. Read more:
Why is "using namespace std;" considered bad practice?
this is not a valid C++ code:
double grade[];
You can use std::vector:
std::vector<double> grade;
To insert a grade to the vector you can use grade.push_back(someGrade);
Related
In my class we recently got introduced to STL vectors. My professor has given us a program that uses arrays, and we are to convert it to use std::vectors instead. He would like us to use iterators, so we're not allowed to use square brackets, the push_back member function, or the at member function. Here's one of the for loops from the program I have to convert:
void readData(Highscore highScores[], int size)
{
for(int index = 0; index < size; index++)
{
cout << "Enter the name for score #" << (index + 1) << ": ";
cin.getline(highScores[index].name, MAX_NAME_SIZE, '\n');
cout << "Enter the score for score #" << (index + 1) << ": ";
cin >> highScores[index].score;
cin.ignore();
}
cout << endl;
}
`
I'm just not quite understanding how to convert them. so far, I was kind of able to get this: for (vector <Highscore> :: iterator num = scores.begin(); num < scores.end(); num++)for the for loop. It doesn't quite make sense to me so I was hoping I can get some more tips or even more information on how to convert them. I don't want an answer, simply just a tip. Thank you! (if its of any help, this is the program I am having to convert and these are the four headers we have to use
void getVectorSize(int& size);
void readData(vector<Highscore>& scores);
void sortData(vector<Highscore>& scores);
vector<Highscore>::iterator findLocationOfLargest(
const vector<Highscore>::iterator startingLocation,
const vector<Highscore>::iterator endingLocation);
void displayData(const vector<Highscore>& scores);
above are the headers that have to be used (having to use these instead of the programs headers)
#include <iostream>
using namespace std;
const int MAX_NAME_SIZE = 24;
struct Highscore{
char name[MAX_NAME_SIZE];
int score;
};
void getArraySize(int& size);
void readData(Highscore highScores[], int size);
void sortData(Highscore highScores[], int size);
int findIndexOfLargest(const Highscore highScores[], int startingIndex, int size);
void displayData(const Highscore highScores[], int size);
int main()
{
Highscore* highScores;
int size;
getArraySize(size);
highScores = new Highscore[size];
readData(highScores, size);
sortData(highScores, size);
displayData(highScores, size);
delete [] highScores;
}
void getArraySize(int& size){
cout << "How many scores will you enter?: ";
cin >> size;
cin.ignore();
}
void readData(Highscore highScores[], int size)
{
for(int index = 0; index < size; index++)
{
cout << "Enter the name for score #" << (index + 1) << ": ";
cin.getline(highScores[index].name, MAX_NAME_SIZE, '\n');
cout << "Enter the score for score #" << (index + 1) << ": ";
cin >> highScores[index].score;
cin.ignore();
}
cout << endl;
}
void sortData(Highscore highScores[], int numItems) {
for (int count = 0; count < numItems - 1; count++){
swap(highScores[findIndexOfLargest(highScores, count, numItems)],
highScores[count]);
}
}
int findIndexOfLargest(const Highscore highScores[], int startingIndex, int numItems){
int indexOfLargest = startingIndex;
for (int count = startingIndex + 1; count < numItems; count++){
if (highScores[count].score > highScores[indexOfLargest].score){
indexOfLargest = count;
}
}
return indexOfLargest;
}
void displayData(const Highscore highScores[], int size)
{
cout << "Top Scorers: " << endl;
for(int index = 0; index < size; index++)
{
cout << highScores[index].name << ": " << highScores[index].score << endl;
}
}
You maybe looking for one of two things.
If you want to add something to a vector, the function is push_back
vecScores.push_back(value) ; //in a for loop.
https://www.cplusplus.com/reference/vector/vector/push_back/
If you want to add something to a map, you could just use the form of
mapScore[index]=value ; // in a for loop.
https://www.cplusplus.com/reference/map/map/operator[]/
Probably your professor wants you to write something like this:
void readData(std::vector<Highscore>& highScores)
{
for (auto it = highScores.begin(); it != highScores.end(); ++it) {
cout << "Enter the name for score #" << std::distance(highScores.begin(), it) << ": ";
cin.getline(it->name, MAX_NAME_SIZE, '\n');
cout << "Enter the score for score #" << std::distance(highScores.begin(), it) << ": ";
cin >> it->score;
cin.ignore();
}
cout << endl;
}
where it is the iterator that's incremented via ++it from highScores.begin() to just before highScores.end(); then you access the members of the highScores's element "pointed by" it via it->member.
Here's a complete demo.
By the way, considering how much your professor likes void(some_type&) functions (and using namespace std;, if that was not your own idea), I would doubt you have much to learn from him. You better buy a good book.
I would do it like this, also get used to typing std::
Why is "using namespace std;" considered bad practice?
Also be careful with signed/unsigned, be precise about it.
If something can't have a negative value use unsigned types (or size_t)
#include <iostream>
#include <string>
#include <vector>
struct HighScore
{
std::string name;
unsigned int score;
};
// use size_t for sizes (value will always >0)
std::vector<HighScore> GetHighScores(size_t size)
{
std::vector<HighScore> highScores;
std::string points;
for (size_t index = 0; index < size; index++)
{
HighScore score;
std::cout << "Enter the name for score #" << (index + 1) << ": ";
std::cin >> score.name;
std::cout << "Enter the score for score #" << (index + 1) << ": ";
std::cin >> points;
// convert string to int
score.score = static_cast<unsigned int>(std::atoi(points.c_str()));
highScores.push_back(score);
}
std::cout << std::endl;
return highScores;
}
int main()
{
auto highScores = GetHighScores(3);
return 1;
}
#include <iostream>
#include <array>
#include <algorithm>
void *swap(int arr[], int size);
void *swap(int arr[], int size) {
int i,j,temp;
for(int i{0}; i < size; i++) {
for(int j{i+1}; j < size; j++) {
if(arr[i] > arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
std::cout <<"The numbers in ascending order are: ";
for(int i{0}; i < size; i++)
std::cout << arr[i] << " ";
}
void average_score(int arr[], int size);
void average_score(int arr[], int size) {
int average {0};
for(int i{0}; i < size; i++) {
average+=arr[i];
}
std::cout << "\nThe average is: " << average / size << std::endl;
}
int main() {
int *test_scores = nullptr;
int n;
std::cout <<"Enter Size: ";
std::cin >> n;
test_scores = new int[n];
int i = 0;
int student_scores;
while(i < n) {
std::cout << "Enter Student " << i+1 << " Test Score: ";
std::cin >> student_scores;
test_scores[i] = student_scores;
i++;
}
swap(test_scores,3);
average_score(test_scores,3);
}
The assignment is also asking me to instead of stepping through the arrays, use pointers rather than array subscripts. I have already created a program where it takes in the test scores and calculates the average and sorts it into ascending order, now I just need to create a display of the student's name right next to their score. Any thoughts or helpful advice that I can use to help me build this program?
In C++ you have a data container called struct that may help you with that. (You can also use classes, but I don't think they are necessary here).
A possible struct for this problem may be declared like this:
struct student {
int grade;
string name;
};
In your main program you could change the test_scores array for a vector, which is more helpful as its size can be modified.
std::vector<student> test_scores(n);
If you want to access the attributes of your student struct you would do so by using the dot operator.
int a = test_scores[0].grade;
string s = test_scores[0].name;
You are given this error because you try to add an int into a student vector. "no matching function call" means that the compiler does not know how to transform the integer into a student. To fix it, I recommend you to ask for the name instead of only asking for the score, so you may add the following code:
student s;
for (int i = 0; i < n; ++i) {
std::cout << "Enter Student " << i+1 << " Name and Test Score: " << endl;
std::cin >> s.name >> s.grade;
test_scores[i] = s; // Don't use test_scores.push_back(s) here, if you do so,
// you would increase its size by 1 and add the element s at the end of the vector.
}
In your average_score function, you should change the int arr[] parameter for a vector <student> &arr and average += arr[i] for average += arr[i].score. The & in &arr is important because it passes the parameter as reference so that its elements are not copied into the function, which is very unnefficient.
Your swap function should be void instead of void *. Also, try using the sort function of the algorithm library. The sorting code you implemented has quadratic cost over the vector length, which is very unefficient if you have a lot of students.
The strange problem appears in my program. It is working, but in debugging it shows the "Exception thrown" in random places at the outputting
cout<<"Average value:"<<u3.apr();
_getch();
Sometimes, it even throws this error after the main function (Behind the {})
It is quite annoying because the program just closes after 3 seconds because of these errors.
(Maybe that's because of class, but I'm trying to learn it ;) )
Have tried already changing lines order, rewriting class name and array name.
#include <iostream>
#include <conio.h>
using namespace std;
class vid
{
private:
int i, j;
double rez, sum=0;
public:
int size;
double *arr = new double[size];
double apr()
{
for (i = 0; i < size; i++)
{
sum += (*(arr + i));
}
return sum / size;
}
};
int main()
{
vid u3;
cout << "Enter array length:";
cin >> u3.size;
for (int i = 0; i < u3.size; i++)
{
cout << "Enter array's " << i << " element:" << endl;
cin >> *(u3.arr+i);
}
cout << "Your array:" << endl;
for (int i = 0; i < u3.size; i++)
{
cout << *(u3.arr + i) << "\t";
}
cout << endl;
cout<<"Average value:"<<u3.apr();
_getch();
}
Thanks for any help ;)
arr is initialised when u3 is constructed.
But you didn't populate u3.size until later.
So, your array has indeterminate length (which is already UB), and your accesses later may be invalid.
You're going to have to manage your class's member a bit more cleverly!
Such classes generally have a "resize" function that performs the allocation per the requested size. Don't forget to safely kill any prior allocation, transplanting data if necessary. You can find online plenty of examples of a vector implementation.
Certainly renaming classes and randomly re-ordering the lines of your program's source code is not going to solve anything.
u3.size is not set until after u3 is constructed. By setting u3.size you can avoid this compiler-time error.
It seems that as an alternative solution, you might want to consider how to get rid of the new call and the need to write a destructor that will delete arr.
By creating a constructor that takes a size parameter AND by switching arr to a std::vector, you can allow the class to hold the vector and handle memory allocation and deallocation:
#include <iostream>
#include <vector>
using namespace std;
class vid
{
private:
int i, j;
double rez, sum=0;
public:
int size;
std::vector<double> arr;
// constructor requires size to be passed in;
// constructor initializes the arr array with the passed in size to zeroes.
vid(int argSize) : size(argSize), arr(argSize, 0.0){ }
double apr()
{
for (i = 0; i < size; i++)
{
sum += arr[i];
}
return sum / size;
}
};
int main()
{
uint size;
cout << "Enter array length:";
cin >> size;
vid u3(size);
for (int i = 0; i < u3.size; i++)
{
cout << "Enter array's #" << i << " element:" << endl;
cin >> u3.arr[i];
}
cout << "Your array:" << endl;
for (int i = 0; i < u3.size; i++)
{
cout << u3.arr[i] << "\t";
}
cout << endl;
cout<<"Average value:"<<u3.apr();
char ch;
cin >> ch;
}
I'm picking up on C++ recently and is trying to code a program which prompts for names for a defined no. of times and inserts each of the input into an array of size-5. The problem happened when I tried to run the following code, my counter, i increases according to the no of len the user input. Why is that so?
#include <iostream>
using namespace std;
int main(){
const int SIZE = 5;
char name[SIZE];
int i;
for (i = 0; i < SIZE; i++){
if (strlen(name) <= 50) {
cout << "Enter a name: \n";
cin >> name[i];
}
}
for (i = 0; i < SIZE; i++){
cout << name[i] << endl;
}
return 0;
}
Output:
if (strlen(name) <= 50) {
You should not call strlen on array which is not initialized.
Use array of strings otherwise
cout << name[i] << endl;
refers to i-th character, not entire string. Or if you want to go with char arrays, you'd need a two dimensional array.
I thing what you indended to do was :
#include <iostream>
using namespace std;
int main(){
const int SIZE = 5;
string names[SIZE];
int i;
for (i = 0; i < SIZE; i++){
cout << "Enter a name: \n";
string name;
cin>>name;
if (strlen(name) <= 50) {
cin >> names[i];
}
}
for (i = 0; i < SIZE; i++){
cout << name[i] << endl;
}
return 0;
}
UNTESTED
The second for loop, which does the output, does this in single characters, incrementing i each time.
To output the string all at once assign a string pointer to name[0] and send that to cout.
I am new to C++. I am trying to solve a problem in the textbook: swap the first and last element in an array. But when I run the code I wrote, nothing happened and even the sentence "Please enter the numbers in the array: " does not show up. Anyone could give some help? Thanks.
#include <iostream>
using namespace std;
int swap(int values[], int size)
{
int temp = values[0];
values[0] = values[size-1];
values[size-1] = temp;
}
int main()
{
const int SIZE = 5;
int test[SIZE];
cout << "Please enter the numbers in the array: " << endl;
int input;
cin >> input;
for(int i=0; i<SIZE; i++)
{
test[i] = input;
}
swap(test, SIZE);
cout << test[SIZE] << endl;
return 0;
}
There were a few mistakes:
You should get the input inside the loop and then assign it to the test array.
When printing the swapped value, access the test array with SIZE-1 instead of SIZE, because array indexes run from 0 to SIZE-1, inclusive.
You declared swap() as returning int, but provided no return statement (this suggests that you haven't enabled enough warnings from your compiler).
#include <iostream>
using namespace std;
void swap(int values[], int size)
{
int temp = values[0];
values[0] = values[size-1];
values[size-1] = temp;
}
int main()
{
const int SIZE = 5;
int test[SIZE];
int input;
cout << "Please enter the numbers in the array: " << endl;
for(int i=0; i<SIZE; i++)
{
cin >> input;
test[i] = input;
}
swap(test, SIZE);
cout << test[SIZE-1] << endl;
return 0;
}
#include <iostream>
using namespace std;
//Here return type should be void as you are not returning value.
void swap(int values[], int size)
{
int temp = values[0];
values[0] = values[size-1];
values[size-1] = temp;
}
int main()
{
const int SIZE = 5;
int test[SIZE];
cout << "Please enter the numbers in the array: " << endl;
//USE LOOP TO TAKE INPUT ONE BY ONE IN AN ARRAY
for(int i = 0; i < SIZE; i++)
cin >> test[i];
swap(test, SIZE);
//USE LOOP TO DISPLAY ELEMENT ONE BY ONE
for(int i = 0; i < SIZE; i++)
cout << test[i] << endl;
return 0;
}