I have been given a task of inputting some student data, like
- option 1: Enter student name and id.
- option 2: input i.d (verify against student id – input option 1), input upto 10 grades for the student and then calculating the average and letter grade for the student
- option 3: output the student name, id and letter grade.
The program has to be written in a Class like structure – with declared variables and functions in the structure.
I have also been given the task for entering the details of 3 students using the Class structure. For simplicity sakes for now I am just writing a program for one student.
The program compiles O.K
First specific encountered problem: When I select option ‘I’ the program lets me input the student name and that’s it! – skips the id input for some reason and continues on.
The problem is that I have been using cin>>and also scanf() as my main input methods – but these and system("Pause") have not been serving me well – I understand system("pause") is not very efficient. In the past I have been advised to use a real string type to represent strings like std::string class from the <string> library.
I would therefore appreciate any help with string classes so I can learn of them.
I believe there may be some other problems with my program but any advice with the string classes thing and my ‘first specific encountered problem’ would helpful to start of with.
So I have written the following program to represent my answer.
#include <iostream>
#include <cstdio>
#include <math.h>
using namespace std;
struct classroom{
char name;
int student_id;
float grades[10];
int num_tests;
float average;
float letter_grade;
void enter_name_id(void);
void enter_grade(int);
void average_grades(int);
void letter_grades(void);
void output_name_id_grade(void);
};
void classroom::enter_name_id(){
cout<<"\n Please enter name of student: \n"<<"\n";
cin>>name;
cout<<"\n Please enter student i.d number: \n"<<"\n";
scanf("%d",student_id);
cout<<"\n"<<student_id;
system("PAUSE");
}
void classroom::enter_grade(int n_tests){
if(n_tests<=10){
cout<<"\n Please enter student test grade: \n"<<"\n";
cin>>grades[n_tests];
}
else{
cout<<"\n You have reached your max number of grades entered!!"<<"\n";
}
system ("PAUSE");
}
void classroom::average_grades(int n_tests){
float sum=0;
int i;
for(i=0;i<n_tests;i++){
sum =sum+grades[i];
}
average=sum/(float)n_tests;
system ("PAUSE");
}
void classroom::letter_grades(void){
if(average>=90){
letter_grade=65;
}
if(average>=80&&average<90){
letter_grade=66;
}
if(average>=70&&average<80){
letter_grade=67;
}
if(average>=60&&average<70){
letter_grade=68;
}
if(average<60){
letter_grade=70;
}
system ("PAUSE");
}
void classroom::output_name_id_grade(void){
cout<<"\ Name I.D Grade "<<"\n";
cout<<name <<" ";
cout<<student_id<<" ";
cout<<(char)letter_grade<<"\n";
system ("PAUSE");
}
int main()
{
classroom a;
char option,answer,ans;
int a_num_tests, id;
a_num_tests=0;
for( ; ;){
cout<<"\nEnter 'I' for Name and I.d, 'G' for grades or 'O' for Data output "<<"\n";
cin>>answer;
switch(answer){
case'I':
a.enter_name_id();
break;
case'G':
cout<<"\n Please enter student i.d number: "<<"\n";
scanf("%d",id);
cout<<"\n"<<id;
if(id==a.student_id){
a_num_tests++;
a.enter_grade(a_num_tests);
cout<<"\n Would you like to enter another grade? 'Y' or 'N': "<<"\n";
cin>>ans;
while(ans=='y'||'Y'){
a_num_tests++;
a.enter_grade(a_num_tests);
cout<<"\n Would you like to enter another grade? 'Y' or 'N': "<<"\n";
cin>>ans;
}
a.average_grades(a_num_tests);
a.letter_grades();
}
else{
cout<<"\n You have entered the wong i.d number!!! \n"<<"\n";
break;
}
case 'O':
a.output_name_id_grade();
break;
default:
cout<<"\n Wong Entry "<<"\n";
break;
}
}
system ("PAUSE");
return 0;
}
So many things to say… why would you write
<< "\n" << "\n"?? You can just put the entire string in one piece,<< "\n\n"… anyway.For input/output, just stick with iostreams, and don’t mix and match C library functions without good cause. Perhaps like so:
Maybe this answer is of some use to you. The input operations should be checked for errors, if you want to write serious code.
Note that token extraction (
>>) reads word by word, sostd::cin >> namewill only read one single word. For something like a name, we prefergetline()for that reason.If you run your program from the command line, you won’t need all those
system("pause")calls, either…Update: It’s not generally a good idea to mix token extraction (
>>) with line reading (getline()), since the former doesn’t gobble up newlines while the latter does. Best to stick to just one of the two, whichever is more appropriate for the input format.If you only use line reading, you still have to process each line, perhaps again by token extraction. To do so, you need a string stream. Include
<sstream>and replace the last line by: