2016-04-24 2 views
0

Ich arbeite durch Accelerated C++, und ich kann das Programm aus Kapitel 4 nicht kompilieren; es ist das erste mit Kopfzeilen. Ich habe auch die Quelle von here heruntergeladen und bekomme den genau gleichen Fehler, den ich mit meinem handkopierten Code sehe, also bin ich nicht sicher, was das Problem ist.Beschleunigte C++: Nicht definierte Symbole für Architektur x86_64

Ich benutze g ++ auf OSX El Capitan. Hier ist die genaue Befehl, den ich verwendet:

$ g++ main.cpp 

Hier ist der Fehler:

Undefined symbols for architecture x86_64: 
    "read(std::__1::basic_istream<char, std::__1::char_traits<char> >&, Student_info&)", referenced from: 
     _main in grades-main-e0475a.o 
    "grade(Student_info const&)", referenced from: 
     _main in grades-main-e0475a.o 
    "compare(Student_info const&, Student_info const&)", referenced from: 
     _main in grades-main-e0475a.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

Und hier ist der Code:

main.cpp

#include <algorithm> 
#include <iomanip> 
#include <ios> 
#include <iostream> 
#include <stdexcept> 
#include <string> 
#include <vector> 
#include "grade.h" 
#include "Student_info.h" 

using namespace std; 

int main() { 

    vector<Student_info> students; 
    Student_info record; 
    string::size_type maxlen = 0; // length of the longest name 

    while (read(cin, record)) { 
    maxlen = max(maxlen, record.name.size()); 
    students.push_back(record); 
    } 

    sort(students.begin(), students.end(), compare); 

    for (vector<Student_info>::size_type i = 0; i != students.size(); i++) { 
    cout << students[i].name << string(maxlen + 1 - students[i].name.size(), ' '); 

    try { 
     double final_grade = grade(students[i]); 
     streamsize prec = cout.precision(); 
     cout << setprecision(3) << final_grade << setprecision(prec); 
    } catch (domain_error e) { 
     cout << e.what(); 
    } 
    cout << endl; 
    } 

    return 0; // success 
} 

grade.h

#ifndef GUARD_grade_h 
#define GUARD_grade_h 

#include <vector> 
#include "Student_info.h" 

double grade(double, double, double); 
double grade(double, double, const std::vector<double>&); 
double grade(const Student_info&); 

#endif 

grade.cpp

#include <stdexcept> 
#include <vector> 
#include "grade.h" 
#include "median.h" 
#include "Student_info.h" 

using namespace std; 

double grade(double midterm, double final, double homework) { 
    return 0.2 * midterm + 0.4 * final + 0.4 * homework; 
} 

double grade(double midterm, double final, const vector<double>& hw) { 
    if (hw.size() == 0) throw doman_error("student has done no homework"); 

    return grade(midterm, final, median(hw)); 
} 

double grade(const Student_info& s) { 
    return grade(s.midterm, s.final, s.homework); 
} 

Student_info.h

#ifndef GUARD_Student_info 
#define GUARD_Student_info 

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

struct Student_info { 
    std::string name; 
    double midterm, final; 
    std::vector<double> homework; 
}; 

bool compare(const Student_info&, const Student_info&); 
std::istream& read(std::istream&, Student_info&); 
std::istream& read_hw(std::istream&, std::vector<double>&); 

#endif 

Student_info.cpp

#include "Student_info.h" 

using namespace std; 

bool compare(const Student_info& x, const Student_info& y) { 
    return x.name < y.name; 
} 

istream& read(istream& is, Student_info& s) { 
    is >> s.name >> s.midterm >> s.final; 

    read_hw(is, s.homework); 
    return is; 
} 

istream& read_hw(istream& in, vector<double>& hw) { 
    if (in) { 
    hw.clear(); 

    double x; 
    while (in >> x) { 
     hw.push_back(x); 
    } 
    in.clear(); 
    } 
    return in; 
} 

median.h

#ifndef GUARD_median_h 
#define GUARD_median_h 

#include <vector> 

double median(std::vector<double>); 

#endif 

median.cpp

#include <algorithm> 
#include <stdexcept> 
#include <vector> 

using namespace std; 

double median(vector<double> vec) { 
    typedef vector<double>::size_type vec_sz; 

    vec_sz size = vec.size(); 
    if (size == 0) throw domain_error("median of an empty vector"); 

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

    vec_sz mid = size/2; 

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

so vielen Dank für Ihre Hilfe, jemand!

+2

anzeigen Befehle die Sie verwenden, um obigen Code zu kompilieren. – gudok

+0

Wenn Sie g ++ verwenden, wie Sie angeben, warum ist der Fehler mit dem Präfix "clang:'? – kfsone

+0

@ gudok fertig. Ich habe 'g ++ main.cpp' @ kfsone verwendet, ich nicht weiß warum der Fehler mit "clang" vorangestellt wurde.Ich bin ein Java-Entwickler, und ich habe C++ - Code nicht kompiliert, seit ich vor fast 20 Jahren auf der High School war - ich glaube, wir haben damals Borland benutzt. – AutonomousApps

Antwort

1

Wie der etwas kryptische Kommentar von @ gudok nahelegt, ist dies höchstwahrscheinlich Ihr erstes Programm mit mehreren Quelldateien. Sie können nicht nur eine Datei kompilieren und eine ausführbare Datei erhalten; Sie müssen jede Datei kompilieren und die resultierenden Objektdateien miteinander verknüpfen. Der einfachste Weg, das zu tun, ist wie folgt:

g++ main.cpp grade.cpp student_info.cpp median.cpp 

Wenn es keine Fehler im Code, die eine ausführbare Datei mit dem Namen „a.out“ im aktuellen Verzeichnis erzeugen.

EDIT: habe gerade bemerkt, dass die Fehlermeldung von „Klirren“ kommt, nicht von „g ++‘ Das ist okay, wenn Sie verwenden. ‚Klappern‘, nur über die Befehlszeile

ändern
clang++ main.cpp grade.cpp student_info.cpp median.cpp 
+0

Danke, das ist genau das, was ich brauchte, außer dass ich 'g ++', nicht 'clang ++ benutzt habe '. Wie gesagt, dies ist mein erstes C++ - Programm mit mehreren Quelldateien, daher kannte ich einfach nicht den richtigen Befehl, um es zu kompilieren. – AutonomousApps