C++ program starting with void PrintTranscript

In summary: No such file or directoryPI.cc:138: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'I'm sorry, I can't continue to debug this for you. You need to understand the error messages and what they mean in your code. I suggest reading a tutorial on C++ vectors and how to access elements in them. Also, make sure you are using the right variable names and that they are in scope. Good luck!
  • #1
Nusc
760
2
void PrintTranscript( const vector <student>& a )
{
cout << "Here is a list of courses that you have taken:" << endl;
for (int i = 0; i<a.size(); i++)
{
line 104: for (int j = 0; j<a.size(); j++)
cout << a.firstname << " " << a.lastname << " " << a.id << endl;
line 106: cout << a.courses[j].session << " " << a.courses[j].year << " " << a.courses[j].coursename << " " << a.courses[j].percentage << " " << a.courses[j].lettergrade << endl;
}
}

PI.cc:106: error: name lookup of `j' changed for new ISO `for' scoping
PI.cc:104: error: using obsolete binding at `j'


Can anyone please help me?
 
Technology news on Phys.org
  • #2
The loop in which j is defined is only one line long. You want more brackets, I think.
 
  • #3
Where do I put the brackets?
 
  • #4
You are referencing j in line 106, so that line should be in the loop over j.

The easiest way to solve this problem is to always code as if the C required braces for all loops and branches. In other words, pretend
for (i=0;i<n;i++) do_something_with(i)
is illegal.

This rule is automatically enforced by code checkers in many programming shops. Get in the habit of always using braces.
 
  • #5
void PrintTranscript( const vector <student>& a )
{
cout << "Here is a list of courses that you have taken:" << endl;
for (int i = 0; i<a.size(); i++)
{
cout << a.at(i).firstname << " " << a.at(i).lastname << " " << a.at(i).id << endl;
for (int j = 0; j<a.size(); j++)
{

cout << a.at(i).courses.at(j).session << " " << a.at(i).courses.at(j).year << " " << a.at(i).courses.at(j).coursename << " " << a.at(i).courses.at(j).percentage << " " << a.at(i).courses.at(j).lettergrade << endl;
}
}
}

Error
undefined reference to `ReadStudent(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<student, std::allocator<student> >&)'

undefined reference to `ComputeGPA(std::vector<student, std::allocator<student> > const&)'


undefined reference to `ReadStudent(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<student, std::allocator<student> >&)'
collect2: ld returned 1 exit status

I don't even understand what this means, what's wrong now?
 
  • #6
Those undefined references (ReadStudent and ComputeGpA) are methods you are invoking but that you have not defined.
 
  • #7
void ReadStudent(string id, vector<student>& a);
void PrintTranscript(const vector<student>& a);
double ComputeGPA(const vector <student>& a);
int main()
{
string id;
string filename;
vector <student> a;

cout <<"Please enter your student ID number"<< endl;
cin >> id;
ReadStudent(id, a);
char choice;

do
{
cout << "What do you wish to do with the database?" << endl;
cout << "Input the relevant letter: Options are" << endl;
cout << "(a) List the courses taken by the student" << endl;
cout << "(b) Compute and display the student's grade point average (GPA)" << endl;
cout << "(c) Open the file of another student" << endl;
cout << "(d) Quit the program" << endl;

cin >> choice;
cout << "You have entered:" << choice << endl;
switch (choice)
{
case ('a'):
PrintTranscript(a);
break;
case ('b'):
ComputeGPA(a);
break;
case ('c'):
cout << "Please enter another student ID" << endl;
cin >> id;
ReadStudent(id,a);
break;
case ('d'):
{
cout << "Program ending" << endl;
}
}
}while(choice != 'd');
return 0;
}

That's my main function, how did I not define those functions?
 
  • #8
You specified prototypes for the functions. You did not define them.

Here is a function prototype, taken from your code:
double ComputeGPA(const vector <student>& a);

Somewhere you have to define the function, which would look like
Code:
double ComputeGPA(const vector <student>& a)
{
  double gpa;
  // Compute the student's GPA
  // GPA code computation omitted
  return gpa;
}
 
  • #9
double ComputeGPA(const vector <student>& a)
{
double GPA = 0;
double sum = 0;
for( int i = 0; i<a.courses.size(); i++)
{
if(a.courses.at(i).lettergrade == "A+")
sum += 4.0;
if(a.courses.at(i).lettergrade == "A")
sum += 4.0;
if(a.courses.at(i).lettergrade == "A-")
sum += 3.7;
if(a.courses.at(i).lettergrade == "B+")
sum += 3.3;
if(a.courses.at(i).lettergrade == "B")
sum += 3.0;
if(a.courses.at(i).lettergrade == "B-")
sum += 2.7;
if(a.courses.at(i).lettergrade == "C+")
sum += 2.3;
if(a.courses.at(i).lettergrade == "C")
sum += 2.0;
if(a.courses.at(i).lettergrade == "C-")
sum += 1.7;
if(a.courses.at(i).lettergrade == "D")
sum += 1.0;
if(a.courses.at(i).lettergrade == "F")
sum += 0.0;
}
GPA = sum/a.courses.size();
cout << "Average GPA:" << GPA << endl;
}
Which gives me:

PI.cc: In function `double ComputeGPA(const std::vector<student, std::allocator<student> >&)':
PI.cc:117: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'
PI.cc:119: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'
PI.cc:121: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'
PI.cc:123: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'
PI.cc:125: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'
PI.cc:127: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'
PI.cc:129: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'
PI.cc:131: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'
PI.cc:133: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'
PI.cc:135: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'
PI.cc:137: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'
PI.cc:139: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'
PI.cc:142: error: 'const class std::vector<student, std::allocator<student> >' has no member named 'courses'

Compilation exited abnormally with code 1 at Mon Apr 16 19:47:14

Those lines correspond to the if(a.courses.at(i).lettergrade == "A-") etc.

If needed:

#include <fstream>
#include <vector>
#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;


struct course
{
char session;
int year;
string coursename;
int coursenumber;
double percentage;
string lettergrade;
};

struct student
{
vector <course> courses;
string firstname;
string lastname;
int id;
};

What's the problem now?
 
Last edited:
  • #10
Your argumet list indicates the funtion is receiving avector of students, but your function body is obviously dealing with just one student. You need to either fix the argument list (just one student, not a vector of students) or fix the function body (compute the GPAs of a vector of students).
 
  • #11
Okay I fixed that
void ReadStudent( string id,vector<student>& a)
{
student tmp;
id += ".txt";
ifstream infile(id.c_str());
infile >> tmp.firstname;
infile >> tmp.lastname;
infile >> tmp.id;
tmp.courses.resize(0);
while(!infile.eof())
{
tmp.courses.push_back(tmp);
int j = tmp.courses.size()-1;
infile >> tmp.courses.at(j).session;
infile >> tmp.courses.at(j).year;
infile >> tmp.courses.at(j).coursename;
infile >> tmp.courses.at(j).coursenumber;
infile >> tmp.courses.at(j).percentage;
infile >> tmp.courses.at(j).lettergrade;
}
}


but now I receive:

PI.cc: In function `void ReadStudent(std::string, std::vector<student, std::allocator<student> >&)':
PI.cc:88: error: no matching function for call to `std::vector<course, std::allocator<course> >::push_back(student&)'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_vector.h:557: note: candidates are: void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = course, _Alloc = std::allocator<course>]

Compilation exited abnormally with code 1 at Mon Apr 16 20:22:51

what does this mean?
 
Last edited:
  • #12
I fixed it. My program compiles but when I run the text file associated with it I get aborted (core dumped).

#include <fstream>
#include <vector>
#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;


struct course
{
char session;
int year;
string coursename;
int coursenumber;
double percentage;
string lettergrade;

};

struct student
{
vector <course> courses;
string firstname;
string lastname;
int id;
};


void ReadStudent(string id, vector<student>& a);
void PrintTranscript(const vector<student>& a);
double ComputeGPA(const vector<student>& a);
int main()
{
string id;
string filename;
vector <student> a;

cout <<"Please enter your student ID number"<< endl;
cin >> id;
ReadStudent(id, a);
char choice;

do
{
cout << "What do you wish to do with the database?" << endl;
cout << "Input the relevant letter: Options are" << endl;
cout << "(a) List the courses taken by the student" << endl;
cout << "(b) Compute and display the student's grade point average (GPA)" << endl;
cout << "(c) Open the file of another student" << endl;
cout << "(d) Quit the program" << endl;

cin >> choice;
cout << "You have entered:" << choice << endl;
switch (choice)
{
case ('a'):
PrintTranscript(a);
break;
case ('b'):
ComputeGPA(a);
break;
case ('c'):
cout << "Please enter another student ID" << endl;
cin >> id;
ReadStudent(id,a);
break;
case ('d'):
{
cout << "Program ending" << endl;
}
}
}while(choice != 'd');
return 0;
}

void ReadStudent( string id,vector<student>& a)
{
student tmp;
id += ".txt";
ifstream infile(id.c_str());
infile >> tmp.firstname;
infile >> tmp.lastname;
infile >> tmp.id;
tmp.courses.resize(0);
while(!infile.eof())
{
//tmp.courses.push_back(tmp);
int j = tmp.courses.size()-1;
infile >> tmp.courses.at(j).session;
infile >> tmp.courses.at(j).year;
infile >> tmp.courses.at(j).coursename;
infile >> tmp.courses.at(j).coursenumber;
infile >> tmp.courses.at(j).percentage;
infile >> tmp.courses.at(j).lettergrade;
a.push_back(tmp);
}
}

void PrintTranscript( const vector <student>& a )
{
cout << "Here is a list of courses that you have taken:" << endl;
for (int i = 0; i<a.size(); i++)
{
cout << a.at(i).firstname << " " << a.at(i).lastname << " " << a.at(i).id << endl;
for (int j = 0; j<a.size(); j++)
{

cout << a.at(i).courses.at(j).session << " " << a.at(i).courses.at(j).year << " " << a.at(i).courses.at(j).coursename << " " << a.at(i).courses.at(j).percentage << " " << a.at(i).courses.at(j).lettergrade << endl;
}
}
}

double ComputeGPA(const vector <student>& a)
{
double GPA = 0;
double sum = 0;
for(int j = 0; j<a.size(); j++)
{
for( int i = 0; i<a.at(j).courses.size(); i++)
{
if(a.at(j).courses.at(i).lettergrade == "A+")
sum += 4.0;
if(a.at(j).courses.at(i).lettergrade == "A")
sum += 4.0;
if(a.at(j).courses.at(i).lettergrade == "A-")
sum += 3.7;
if(a.at(j).courses.at(i).lettergrade == "B+")
sum += 3.3;
if(a.at(j).courses.at(i).lettergrade == "B")
sum += 3.0;
if(a.at(j).courses.at(i).lettergrade == "B-")
sum += 2.7;
if(a.at(j).courses.at(i).lettergrade == "C+")
sum += 2.3;
if(a.at(j).courses.at(i).lettergrade == "C")
sum += 2.0;
if(a.at(j).courses.at(i).lettergrade == "C-")
sum += 1.7;
if(a.at(j).courses.at(i).lettergrade == "D")
sum += 1.0;
if(a.at(j).courses.at(i).lettergrade == "F")
sum += 0.0;
GPA = sum/a.at(j).courses.size();
}
}

cout << "Average GPA:" << GPA << endl;
return GPA;
}
 
  • #13
Why are you pushing a student (tmp) onto a vector of courses?

Don't program by guessing. Think about what you want the program to do and what you are telling it to do.

Edited to add:
The above response was to post #11.

It looks like you are still programming by guessing.

For example, what makes you want to have a vector of students at all, when you are only dealing with one student at a time?
 
Last edited:
  • #14
Sorry the test file is:

123456.txt

John Smith 123456
F 2005 ENGG 205 62 C-
W 2006 ECON 209 79 B+
W 2006 ENGG 233 85 A
 
  • #15
I don't want a vector of students. I want a vector that will read this line say:

F 2005 ENGG 205 62 C-
 
  • #16
That function is still reading one student.

Can someone please tell me how to fix this?

One chance to help, one chance to write a final.
 
Last edited:
  • #17
Where can I go for help?
 
  • #18
You seem to be having tremendous problems just getting your code to compile, which indicates deep misunderstandings of the basics. You should get some help from your professor or TA immediately. Your needs may well be beyond what we can provide on an a forum.

- Warren
 
  • #19
The program compiles but I receive the following when running my program:
Aborted (core dumped)

My professor doesn't know C++ very well nor does my TA.
 
  • #20
Okay. I finally got the program to read the text file.

However, when it computes the average GPA it only says 3 which is not correct.

double ComputeGPA(const vector <student>& a)
{
double GPA = 0;
double sum = 0;
for(int j = 0; j<a.size(); j++)
{
for( int i = 0; i<a.at(j).courses.size(); i++)
{
if(a.at(j).courses.at(i).lettergrade == "A+")
sum += 4.0;
if(a.at(j).courses.at(i).lettergrade == "A")
sum += 4.0;
if(a.at(j).courses.at(i).lettergrade == "A-")
sum += 3.7;
if(a.at(j).courses.at(i).lettergrade == "B+")
sum += 3.3;
if(a.at(j).courses.at(i).lettergrade == "B")
sum += 3.0;
if(a.at(j).courses.at(i).lettergrade == "B-")
sum += 2.7;
if(a.at(j).courses.at(i).lettergrade == "C+")
sum += 2.3;
if(a.at(j).courses.at(i).lettergrade == "C")
sum += 2.0;
if(a.at(j).courses.at(i).lettergrade == "C-")
sum += 1.7;
if(a.at(j).courses.at(i).lettergrade == "D")
sum += 1.0;
if(a.at(j).courses.at(i).lettergrade == "F")
sum += 0.0;
GPA = sum/a.at(j).courses.size();
}
}

cout << "Average GPA:" << GPA << endl;
return GPA;
}

If I take out the GPA = sum/a.courses.size() out of the for loop I get an error.
 
  • #21
Nusc said:
GPA = sum/a.at(j).courses.size();

This line is probably doing integer division, when you really want floating point division. Cast the size() result to double like this:

GPA = sum/double(a.at(j).courses.size());

- Warren
 
  • #22
chroot said:
This line is probably doing integer division, when you really want floating point division. Cast the size() result to double like this:

GPA = sum/double(a.at(j).courses.size());

- Warren

The line is doing floating point division (sum is a double).

However, Warren is right. You should still cast size to a double. Don't rely on implicit casts.

The GPA of 3.0 is correct. From post #14, John Smith received an A (4.0), a B+ (3.3), and a C- (1.7). The GPA is (4.0+3.3+1.7)/3 = 9.0/3 = 3.0.
 

What is the purpose of starting a C++ program with void PrintTranscript?

The purpose of starting a C++ program with void PrintTranscript is to print out the transcript or output of the program to the console or terminal. This function can be used to display important information or results to the user.

How do you declare the PrintTranscript function in a C++ program?

The PrintTranscript function can be declared in a C++ program by using the keyword "void" followed by the function name "PrintTranscript" and a set of parentheses. For example: void PrintTranscript().

What is the syntax for calling the PrintTranscript function in a C++ program?

The syntax for calling the PrintTranscript function in a C++ program is to use the function name followed by a set of parentheses. For example: PrintTranscript();

Can the PrintTranscript function be used to print out any type of data in a C++ program?

Yes, the PrintTranscript function can be used to print out any type of data in a C++ program as long as it is formatted correctly. This function can be used to print out integers, floating-point numbers, characters, strings, and more.

Is it necessary to include the iostream library in a C++ program when using the PrintTranscript function?

Yes, it is necessary to include the iostream library in a C++ program when using the PrintTranscript function. This library contains the necessary code for printing out data to the console or terminal.

Similar threads

  • Programming and Computer Science
Replies
12
Views
1K
  • Programming and Computer Science
3
Replies
75
Views
4K
  • Programming and Computer Science
Replies
23
Views
1K
  • Programming and Computer Science
2
Replies
36
Views
2K
  • Programming and Computer Science
Replies
6
Views
8K
Replies
10
Views
956
  • Programming and Computer Science
Replies
30
Views
2K
  • Programming and Computer Science
Replies
23
Views
2K
  • Programming and Computer Science
Replies
4
Views
5K
  • Programming and Computer Science
Replies
17
Views
1K
Back
Top