hbye5111
hbye5111

Reputation: 19

c++ header files, Undefined symbols for architecture x86_64

I'm trying to build a program to store student grades in C++. I'm receiving the following error when compiling:

Undefined symbols for architecture x86_64: "grade1(Student_records const&)", referenced from:
 _main in gradereport-a0007a.o

 "compare(Student_records const&, Student_records const&)", 

referenced from: _main in gradereport-a0007a.o

"read_info(std::__1::basic_istream<char, std::__1::char_traits<char> >&, Student_records&)", 

referenced from: _main in gradereport-a0007a.o

ld: symbol(s) not found for architecture x86_64

The command I have been (trying) to use to compile: g++ gradereport.cpp

The told me that something about my read_info, compare, and grade1 functions were wrong (improperly defined). But, I cannot seem to find the issue.

From reading through prior posts on "undefined symbols" issues, it seems that either (a) my function declarations do not match or (b) I need to compile multiple files "at the same time" (for lack of a better phrase). I'm pretty sure it is not (a). If (b), how precisely would I accomplish this task? Also, if anybody has any basic criticism, I would love to hear it. Thanks in advance.

Here's my code:

gradereport.cpp

#include<iostream>
#include<ios>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<stdexcept>
#include "student_records.h"
#include "Grades.h"

using std::cout;
using std::endl;
using std::vector;
using std::cout;
using std::cin;
using std::string;
using std::max;
using std::domain_error;

int main()
{

    vector<Student_records> students; 
    Student_records record; 
    string::size_type maxlen = 0;

    while(read_info(cin, record))
    {

        maxlen = max(maxlen, record.name.size()); // finds the longest name
        students.push_back(record); // enters each record into the vector

    }

    sort(students.begin(), students.end(), compare); 
    for(vector<Student_records>::size_type i = 0; i != students.size(); ++i)
    {

        cout << students[i].name
            << string(maxlen + 1 - students[i].name.size(), ' ');

        try
        {

            double final_grade = grade1(students[i]);
            /* need to define grade function:
                1) unpack grades;
                2) find homework grades;
                3) find final grade;
            */
            cout << final_grade

        }

        catch(domain_error e)
        {

            cout << e.what();

        }

        cout << endl;

    }

    return 0;

}

student_records.h

#ifndef GUARD_STUDENT_RECORDS
#define GUARD_STUDENT_RECORDS

#include<iostream>
#include<string>
#include<vector>

struct Student_records
{

    std::string name;
    double midterm, final;
    std::vector<double> homeworks;

};

bool compare(const Student_records&, const Student_records&);
std::istream& read_info(std::istream&, Student_records&);
std::istream& read_homework(std::istream&, std::vector<double>&);

#endif

student_records.cpp

#include "student_records.h"

bool compare(const Student_records& x, const Student_records& y)
{

    return x.name < y.name;

}

std::istream& read_info(istream& is, Student_records& s)
{

    std::cout << "Enter name, midterm, and final: ";
    is >> s.name >> s.midterm >> s.final;

    read_homework(std::istream&, std::vector<double>&);

    return is;

}

std::istream& read_homework(std::istream& in, std::vector<double>& homework)
{

    cout << "Enter homework: ";

    if(in)
    {
        hw.clear()

        double x;
        while(in >> x)
            homework.push_back(x);

        in.clear();
    }

    return in;

}

Grades.h

#ifndef GUARD_GRADES
#define GUARD_GRADES

#include<iostream>
#include<vector>
#include<string>
#include "student_records.h"

double grade1(const Student_records&);
double grade2(double, double, std::vector<double>);
double median(std::vector<double>);

#endif

Grades.cpp

#include<stdexcept>
#include<vector>
#include "grades.h"
#include "Student_records.h"

using std::domain_error;
using std::vector;

double grade2(double midterm, double final, std::vector<double> homework)
{

    double final_homework_grade;

    final_homework_grade = median(homework);

    return .4 * final_homework_grade + .4 * final + .2 * midterm;

}

double median(vector<double> homework)
{

    typedef vector<double>::size_type vec_sz;

    vec_sz size = homework.size();

    if(size == 0)
        throw domain_error("student has done no homework");

    sort(homework.begin(), homework.end());

    return size % 2 == 0 ? ((homework[mid] + homework[mid + 1]) / 2) : homework[mid];

}

double grade1(const Student_records& s) // unpacks grades
{

    return grade2(s.midterm, s.final, s.homework);

}

Upvotes: 1

Views: 4039

Answers (1)

Pendragon
Pendragon

Reputation: 81

The issue has been already solved in this forum.

The issue arises because you are not compiling all .cpp or .cc files and hence the compiler fails to recognize the inclusions added by your header file.

I hope this helps somebody.

Upvotes: 4

Related Questions