I just started learning pointer. I wanted to call the selection sort function to sort a structure array by the test scores, but the function call had an error: invalid conversion from 'int' to 'Student*'. I am not even sure the rest of my codes are correct because I just try and error to write the codes. Thanks a lot!
Do you want the selectionSort function to be able to sort an array of Students based on different criteria and that is why you are trying to pass the testScore as argument to the functions? Well, in that case it becomes a bit more complicated and you might want to use templates or function pointers to be be able to pass in a comparison function, but since you have just started with pointers I'm guessing this is a bit too advanced right now.
If you just want the selectionSort function to always sort by testScore you need to change the code to use testScore as the value, instead of the Sutdent object (which is not even an int).
#include <iostream>
#include <string>
// #include <vector>
struct student
{
std::string name ;
int score = 0 ;
};
// student_info: pointer to the first student in the array to be sorted
// num_students: number of students
void selection_sort( student student_info[], int num_students )
{
if( num_students < 2 ) return ; // nothing to be done
// get the index of the student with the lowest score
int pos_lowest = 0 ;
for( int i = 1 ; i < num_students ; ++i )
if( student_info[i].score < student_info[pos_lowest].score ) pos_lowest = i ;
// bring the student with the lowest score to the front of the sequence
student temp = student_info[0] ;
student_info[0] = student_info[pos_lowest] ;
student_info[pos_lowest] = temp ;
// leave the student at the front of the sequence (one with the lowest score)
// as it is and sort the remaining num_students-1 students in the array
// student_info: pointer to first student in the array
// student_info+1: pointer to second student in the array
selection_sort( student_info+1, num_students-1 ) ;
}
int get_test_score()
{
int score ;
std::cout << "score? " ;
constint MAX_TEXT_SCORE = 100 ;
// if the user entered a valid score, return it
if( std::cin >> score && score > 0 && score <= MAX_TEXT_SCORE ) return score ;
std::cout << "please enter a non-negative number not more than "
<< MAX_TEXT_SCORE << '\n' ;
// recover from really bad (non-numeric) input: eg 'abcd'
// you may ignore these two lines for now
std::cin.clear() ;
std::cin.ignore( 1000, '\n' ) ;
return get_test_score() ;
}
int main()
{
// avoid dynamic memory allocation
// consider using std::vector https://cal-linux.com/tutorials/vectors.htmlconstint MAX_NUM_STUDENTS = 1024 ;
student student_info[MAX_NUM_STUDENTS] ;
int num_students ;
std::cout << "how many students? " ;
std::cin >> num_students ;
if( num_students > MAX_NUM_STUDENTS ) num_students = MAX_NUM_STUDENTS ;
for( int i = 0 ; i< num_students ; ++i )
{
std::cout << "name? " ;
std::cin >> student_info[i].name ; // we assume that the name does not contain spaces
student_info[i].score = get_test_score() ;
}
// implicit conversion from array to pointer to the first element of an array.
// https://en.cppreference.com/w/cpp/language/array#Array-to-pointer_decay
selection_sort( student_info, num_students ) ;
// print the sorted list
for( int i = 0 ; i < num_students ; ++i )
std::cout << student_info[i].name << " - " << student_info[i].score << '\n' ;
}
To Perter87:
Thank you for your help. I amended my codes as you suggested. Now it runs, but I can't enter the students' name. The running case is shown below:
------------------------------------------------------------------------
How many students do you wish to process? 5
Enter the information below
Student 1
Name:
Score: 86
Student 2
Name:
Score: -9
Invalid input. Please enter a positive number: 98
Student 3
Name:
Score: 73
Student 4
Name:
Score: 62
Student 5
Name:
Score: 86
The test scores in ascending order are:
Name: Test score: 62
Name: Test score: 73
Name: Test score: 86
Name: Test score: 86
Name: Test score: 98
The average of these 5 students' test scores is 81.00
--------------------------------------------------------------------------
I also amended my codes to ask for the number of students instead of the tests. I hope to the names and the test scores can be matched. Is there anyhting wrong with the getline? Why can't I enter the names? Thank you!
To JLBorges:
Thank you for your time and codes. I have to practice the pointers, that's why I have to dynamically allocate the array. Your codes work perfectly. Thank you!
Now it runs, but I can't enter the students' name.
The problem is that >> doesn't consume the newline character that comes after the value. If getline comes after, it will find the newline character right away, giving you an empty string, without waiting for more input.
after you have used the >> operator in order to discard the rest of the line so that if getline follows it will start reading on the next line instead of what's left of the old one.
Or always use std::ws before using getline in order to discard all whitespaces (including newlines) before reading the line.
std::getline(std::cin >> std::ws, line);
This is probably easier but doesn't work if you care about whitespace characters at the beginning of the line (which I don't think you do in this case).
To Peter87
Thank you! I just added "cin.ignore()", and it worked. The only problem was that I couldn't control the formatting of the output, but my instructor was okay with it. I also amended my selection sort function to sort the whole structure by the test scores. Here is the new code:
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
struct Student
{
string name;
int testScore;
Student()
{
name="unknown";
testScore=0;
}
};
void selectionSort(Student [], int);
double calAverage(double, int);
int main()
{
Student *student=NULL;
int numStud=0;
double total=0.0;
cout << "How many students do you wish to process? ";
cin >> numStud;
cout << endl;