0

在必须将程序编写为面向对象代码的情况下进行分配。

编辑:使用 VS2012 命令行编译器,命令“cl History.cpp -EHs”

当我尝试编译时,我得到了错误

History.obj
History.obj : error LNK2019: unresolved external symbol "public: void __thiscall Course::setName(char * const)" (?setNam
e@Course@@QAEXQAD@Z) referenced in function _main
History.obj : error LNK2019: unresolved external symbol "public: void __thiscall Course::setTerm(char * const)" (?setTer
m@Course@@QAEXQAD@Z) referenced in function _main
History.obj : error LNK2019: unresolved external symbol "public: void __thiscall Course::setUnits(int)" (?setUnits@Cours
e@@QAEXH@Z) referenced in function _main
History.obj : error LNK2019: unresolved external symbol "public: void __thiscall Course::setGrade(char)" (?setGrade@Cour
se@@QAEXD@Z) referenced in function _main
History.obj : error LNK2019: unresolved external symbol "public: void __thiscall Course::printCourse(void)const " (?prin
tCourse@Course@@QBEXXZ) referenced in function "void __cdecl printClasses(class std::list<class Course,class std::alloca
tor<class Course> > &)" (?printClasses@@YAXAAV?$list@VCourse@@V?$allocator@VCourse@@@std@@@std@@@Z)
History.obj : error LNK2019: unresolved external symbol "public: static bool __cdecl Course::compareNames(class Course,c
lass Course)" (?compareNames@Course@@SA_NV1@0@Z) referenced in function _main
History.obj : error LNK2019: unresolved external symbol "public: static bool __cdecl Course::compareTerms(class Course,c
lass Course)" (?compareTerms@Course@@SA_NV1@0@Z) referenced in function _main
History.obj : error LNK2019: unresolved external symbol "public: static bool __cdecl Course::compareUnits(class Course,c
lass Course)" (?compareUnits@Course@@SA_NV1@0@Z) referenced in function _main
History.obj : error LNK2019: unresolved external symbol "public: static bool __cdecl Course::compareGrades(class Course,
class Course)" (?compareGrades@Course@@SA_NV1@0@Z) referenced in function _main
History.exe : fatal error LNK1120: 9 unresolved externals

我的文件是 Course.h、Course.cpp 和 History.cpp

Course.h 文件是:

#ifndef COURSE_H 
#define COURSE_H

//////////////////////////////
/* struct/class definitions */
//////////////////////////////

class Course
{
  private: 
  char name[11];
  char term[7];
  int units;
  char grade;

  public: 
  void setName(char[]);
  void setTerm(char[]);
  void setUnits(int);
  void setGrade(char);

  void printCourse() const;
  static bool compareNames(Course, Course) ;
  static bool compareTerms(Course, Course) ;
  static bool compareUnits(Course, Course) ;
  static bool compareGrades(Course, Course) ;
  static bool CourseCmp(Course, Course) ;


};


#endif

Course.cpp 是

// Lab 15 - Course.cpp
// Programmer: Dan Tahir
// Editor(s) used: notepad++
// Compiler(s) used: VC++ 2010 Express

#include "Course.h"

#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::ios;

#include <iomanip>
using std::setprecision;
using std::setw;


#include <cstring>



int myStricmp(const char* dst, const char* src)
{
  int f, l;
  do
  {
    if (((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z')) f -= 'A' - 'a';
    if (((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z')) l -= 'A' - 'a';
  } while (f && (f == l));
  return(f - l);
}

int myStrnicmp(const char* dst, const char* src, int count)
{
  int f, l;
  do
  {
    if (((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z')) f -= 'A' - 'a';
    if (((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z')) l -= 'A' - 'a';
  } while (--count && f && (f == l));
  return (f - l);
}

//setters
void Course::setName(char enteredName[])
{
  strcpy(name, enteredName);
}

void Course::setTerm(char enteredTerm[])
{
  strcpy(term, enteredTerm);
}
void Course::setUnits(int enteredUnits)
{
  units = enteredUnits;
}
void Course::setGrade(char enteredGrade)
{
  grade = enteredGrade;
}

//getters
void Course::printCourse() const
{
  cout.setf(ios::left, ios::adjustfield);

  cout 
    << setw(12) 
    << name 
    << setw(10) 
    << term 
    << setw(7) 
    << units 
    << setw(7) // doesn't matter for last row but whatev
    << grade << endl;  

}

static bool Course::compareNames(Course a, Course b) 
{

  bool result = false;
  if ( strcmp( a.name , b.name ) == 0 ) result = true;
  return result;

}

static bool Course::compareTerms(Course a, Course b) 
{

  bool result = false;
  if ( strcmp( a.term , b.term ) > 0 ) result = true;
  return result;

}

bool Course::compareUnits(Course a, Course b) 
{

  bool result = false;
  if ( a.units > b.units ) result = true;
  return result;

}

bool Course::compareGrades(Course a, Course b)
{

  bool result = false;
  if ( a.grade > b.grade ) result = true;
  return result;

}   


/*//////////////////
COURSE COMPARE
//////////////////*/

bool Course::CourseCmp ( const Course a, const Course b)
{
  // validate string length
  if ( ( strlen( a.term ) != 6) || ( strlen( b.term ) != 6 ) )
  {
    if ( myStricmp( a.name, b.name ) < 1 )
      return true;
    else 
      return false;
  }

  // handle ties
  if( myStricmp( a.term, b.term ) == 0 )
  {
    if ( myStricmp( a.name, b.name ) < 1 )
      return true;
    else 
      return false;
  }

  // compare the years
  int yearA = atoi( a.term + 2 );
  int yearB = atoi (b.term + 2);
  if( yearA < yearB )
    return true; // termA comes first
  if( yearA > yearB )
    return false; // termB comes first

  // compare semesters in case of same year
  if( myStrnicmp( a.term, "SP", 2 ) == 0 )
    return true;
  if( myStrnicmp( a.term, "SU", 2 ) == 0 )
    return myStrnicmp( b.term, "SP", 2 ) ? true : false;
  return false; // does this if myStrnicmp would == 0 for FA


}    

History.cpp 是

#include "Course.h"

#include <fstream>
using std::fstream;

#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::ios;

#include <iomanip>
using std::setprecision;
using std::setw;

#include <list>
using std::list;

#include <sstream>
using std::ostringstream;

#include <vector>


#include <cctype> // use for: tolower(), toupper()
#include <cstdlib> // use for: atof(), atoi()




///////////////////////
/* const definitions */
///////////////////////







///////////////////////// 
/* function prototypes */
/////////////////////////

void printClasses(list<Course>& );
void restoreList(list<Course>&);
void saveList(list<Course>&);

///////////////////
/* main function */
///////////////////

int main()
{
  /////////////////
  /* TITLE BLOCK*/
  /////////////////
  {
    // print my name and this assignment's title
    cout << "Lab 15 - History.cpp" << endl;
    cout << "Programmer: Dan Tahir" << endl << endl;
  }

  ////////////////////////
  /* ASSIGNMENT CONTENT */
  ////////////////////////


  list<Course> courseList;





  // begin data import loop

  while (true)
  {

    /*
      data import - user choice entry
      ask the user whether to read Course history from the file
    */

    cout << "Would you like to import your saved Course data?" << endl;
    cout << "[y] to import, [n] to start with a blank list:" << endl;

    char yOrN = 0;
    cin >> yOrN;
    cin.ignore(1000,10);
    cout << endl;

    yOrN = tolower(yOrN);

    /*
      data imort loop - userchoice response statement
      - if user said y
        - read from file 
        - set tail
        - break 
      - if user said n, break
      - for any other input output an error message then rerun the loop
    */

    if ( 'y' == yOrN )
    {
      // god willing, the list will be loaded here
      restoreList(courseList);



      // exit loop
      break;

    }
    else if ( 'n' == yOrN )
    { 
      // exit loop
      break;
    }
    else
    {
      cout << "Invalid entry! Press [ENTER] to retry" << endl;
      cin.get();
    }


  }



    // begin print/add classes loop
  while (true)
  {


    /*
      ask the user to add a Course. 
      take input from the user for the if statement below
      y or n - y to add a class, n to quit
      use tolower so Y/N work too
    */
    cout << "would you like to add a Course to your schedule?" << endl;
    cout << "[y] to add, [n] to print ordered Courselists, then quit: ";

    char yOrN = 0;
    cin >> yOrN;
    cin.ignore(1000,10);
    cout << endl;

    yOrN = tolower(yOrN);

    /*
      BEGIN USER Y/N IF STATEMENT
      - if user said y, run the add-class dequence in that
      if consequential
      - if user said n, print again then exit the print/add loop
      - for any other input output an error message then rerun the loop
    */
    if ('y' == yOrN)
    {
      /*
        Course input sequence
        - begin by declaring a new Course and assigning it
        to a pointer
        - take input from the user on a single line, then output to the pointed Course's data members
      */
      Course courseToAdd;

      cout <<"Please enter your Course information on a single line as follows:" << endl
        << "[CourseNAME] [TERM] [UNITS] [GRADE]" << endl << endl;

      char tempName[11];
      cin >> tempName;
      courseToAdd.setName(tempName);

      char tempTerm[7];
      cin >> tempTerm;
      courseToAdd.setTerm(tempTerm);


        // added all this to make sure only a single
        // digit is taken, note - ask if there's a 
        // better way to do this

      char unitBufferA[32];
      char unitBufferB[2] = {0};

      cin >> unitBufferA;
      unitBufferB[0] = unitBufferA[0];

      courseToAdd.setUnits( atoi( unitBufferB ) );

      char tempGrade;
      cin >> tempGrade;
      courseToAdd.setGrade(tempGrade);

      cin.ignore(1000, 10);

      // end Course input sequence


      /*
        Course ADDITION SEQUENCE
        - add new Course at (i guess the front) of list
        - i guess all of this is handled by pushback basically
      */


      courseList.push_back(courseToAdd);




      // end Course addition sequence
    }
        else if ( 'n' == yOrN )
    {
      // nothin fancy here just print and exit

      cout << "your Course schedule: " << endl << endl;

      printClasses(courseList);






      break;
    }
    else 
    {
      // silly user put a wrong answer, let them know
      // they messed up
      cout << "Invalid entry! Press [ENTER] to retry" << endl;
      cin.get();

    }

  }// end print/add classes loop

  // save list

  saveList(courseList);

  // print ordered Courses

  cout << "Your Courses by Name: " << endl << endl;
  courseList.sort(Course::compareNames); 
  printClasses(courseList);

  cout << "Your Courses by Term: " << endl << endl;
  courseList.sort(Course::compareTerms); 
  printClasses(courseList);

  cout << "Your Courses by Credit Units: " << endl << endl;
  courseList.sort(Course::compareUnits); 
  printClasses(courseList);

  cout << "Your Courses by Grades: " << endl << endl;
  courseList.sort(Course::compareGrades); 
  printClasses(courseList);


} // end main






//////////////////////////
/* function definitions */
//////////////////////////

void printClasses(list<Course>& courseList)
{
  cout.setf(ios::left, ios::adjustfield);

  cout << setw(12) << "Course" << setw(8) << "TERM" << setw(7) << "UNITS" << "GRADE" << endl;

  cout << setw(12) << "----------" << setw(8) << "------" << setw(7) << "-----" << "-----" << endl;

  for (list<Course>::iterator p = courseList.begin(); p != courseList.end(); p++)
  {
    p->printCourse();
  }

  cout << setw(12) << "----------" << setw(8) << "------" << setw(7) << "-----" << "-----" << endl << endl;

}


void restoreList(list<Course>& courseList)
{
 fstream fin; 
  fin.open("Courses.dat", ios::binary|ios::in); 
  if (!fin) 
    return;

  // read the number of objects from the disk file 
  int nRecs; 
  fin.read((char*)&nRecs, sizeof(int));

  // read the objects from the disk file 
  // editing to use a queue insert here
  // note: will have to set the tail outside of this function in the if statement that calls it, since I have to use this function's return to return the head and i'm not messing around with pointer-pointers



  for (int i = 0; i < nRecs; i++) 
  { 
    Course courseToAdd;
    fin.read((char*)&courseToAdd, sizeof(Course));

    courseList.push_back(courseToAdd);

  } 
  fin.close(); 

}
// end restoreList function
///////////////////////////



void saveList(list<Course>& courseList)
{

  // open savestream
  fstream fSave; 
  fSave.open("Courses.dat", ios::binary|ios::out); 

  // count objects in list

  int courseCountInt = courseList.size();

  // write count of classes to the file

  fSave.write((char*)&courseCountInt, sizeof(int)); 

  // write the classes to the file

  for (list<Course>::iterator p = courseList.begin(); p != courseList.end(); p++)
  {
    Course c = *p;
    fSave.write((char*)&c, sizeof(Course));
  }


   fSave.close(); 

}

我不允许在 History.cpp 中使用 #include "Course.cpp"。

Course.h 中 Course 类的成员函数必须在 Course.cpp 中定义。

我认为我在定义函数时做错了,但我一辈子都看不到它是什么。

编辑:回应人们留下的评论 -

  • 我使用的编译命令是“cl History.cpp -EHs”,就像我用于单文件程序一样。我假设问题必须与代码有关,但可能只是有一些不同的选项集或用于编译我完全错过的多文件程序的不同过程。

  • “布尔”函数的定义最初并没有“静态”,我补充说,在尝试查看我在类中的声明与 .cpp 中的定义之间是否有任何不匹配的过程中

4

0 回答 0