Link to home
Start Free TrialLog in
Avatar of temulus
temulus

asked on

gcc compilation error, compiles fine under visual c++, please help

I currently have another identical question open, which would not let me add more than 500 points.  So whoever answers this questions will get the points for both.

This program was for an assignment that I had for my Intro to C++ class.  I am not asking for others to do my homework, the assignment has already been turned in and class is finished.

I could not get the program to compile correctly using gcc version 3.2.  I asked the instructor for assistance and she pointed out that the program compiled fine under Microsoft Visual C++.  So in order to get the program completed, I finished it using Visual C++.

My professor, and the rest of my class for that matter, uses Visual C++ and has limited knowledge of gcc and issues involved with using gcc.  I, however, will not be programming for the Windows platorm at all, so I would like to learn what I did wrong in my program in order for it to compile under gcc.

When I try to compile the program I get the following errors:

/tmp/cct1iilo.o: In function `main':
/tmp/cct1iilo.o(.text+0x2e): undefined reference to `Movie::openDBFile()'
/tmp/cct1iilo.o(.text+0x40): undefined reference to `Movie::printMainMenu() const'
/tmp/cct1iilo.o(.text+0xb2): undefined reference to `Movie::addMovie()'
/tmp/cct1iilo.o(.text+0xc9): undefined reference to `Movie::delMovie()'
/tmp/cct1iilo.o(.text+0xe0): undefined reference to `Movie::userSearch()'
/tmp/cct1iilo.o(.text+0xf4): undefined reference to `Movie::listMovies() const'
/tmp/cct1iilo.o(.text+0x108): undefined reference to `Movie::rentMovie()'
/tmp/cct1iilo.o(.text+0x11c): undefined reference to `Movie::returnMovie()'
/tmp/cct1iilo.o(.text+0x17a): undefined reference to `Movie::saveDBFile()'
collect2: ld returned 1 exit status

Here is my code in case you need it.  I can also email the files to you if you prefer:

**** start of client program file   Movie-store.cpp *******
#include"Movie.h" //preprocessor directives
#include <iostream>
#include <iomanip>
#include <cctype>

using namespace std;

int main()
{

   Movie videodb; //variable of class type Movie
   char answer;
   system("tput clear");

   videodb.openDBFile();

   do
   {
       videodb.printMainMenu();
       cin >> answer;
       answer = toupper(answer);

       switch(answer) {
           case 'A':  videodb.addMovie(); break;
           case 'D':  videodb.delMovie(); break;
           case 'S':  videodb.userSearch(); break;
           case 'L':  videodb.listMovies(); break;
           case '-':  videodb.rentMovie(); break;
           case '+':  videodb.returnMovie(); break;
           case 'Q':  cout << "\n\nThank you for using the Video Management System.\n\n";break;
           default:   cout << "\n\nError in choice.  Please try again.\n"  << endl;
       }
   } while (answer != 'Q');
   videodb.saveDBFile();
   return 0;
}
**** end of client program file   Movie-store.cpp *******


**** start of specification file   Movie.h *******
#include <iostream>

using namespace std;

const int Max_Video=100;

struct MovieType  //define our struct to use in our class
{
   char title[80];
   char genre[12];
   char moviestar1[30];
   char moviestar2[30];
   int totalNumCopies;
   int numAvailCopies;
};

class Movie
{
   public:

   void printMainMenu() const;

   void chooseGenre(char[12]);
   // uses a menu to select a genre
   // Precondition: user has chosen function which needs a genre defined
   // Postcondition: defines a genre for addition of title etc.

   void addMovie();
   // user adds a movie title to the db
   // Precondition:  video list has been read into memory
   // Postcondition: the new title is added to the video list

   void delMovie();
   // user deletes a movie title from the db
   // Precondition:  video list has been read into memory, and title
   // is found in the list
   // Postcondition: the title is deleted from the video list

   void listMovies() const;
   // Precondition:  video list has been read into memory
   // Postcondition: the entire list of movies is printed to the screen

   void userSearch();
   // Function to prompt for user defined pattern to search for
   // Precondition:  video list has been read into memory and the users search
   // results in a matching title
   // Postcondition: the results of the search are printed to the screen

   void searchMovies(char[10], char[80], int[], int&);
   // Generalized search function
   // Precondition:  video list has been read into memory, and title is found
   // Postcondition: the results from the search are returned to the calling
   // function

   void rentMovie();
   // Marks a movie as rented
   // Precondition:  video list has been read into memory, and title is found
   // Postcondition: the avail number for the title is decreased by 1

   void returnMovie();
   // Marks a movie as returned to store
   // Precondition:  video list has been read into memory, and title is found
   // Postcondition: the avail number for the title is increased by 1

   int openDBFile();
   // Precondition:  video list file is opened successfully
   // Postcondition: the video list contains entries from the db file

   void saveDBFile();
   // Precondition:  video list file is opened successfully
   // Postcondition: the video list is written to the db file

   int compareStrings(char[80],char[80]);
   //strcmpi does not exist for gcc, this is a workaround
   //Precondition:  two input strings
   //Postcondition:  results determine whether or not strings match
   MovieType videos[Max_Video];
   private:

//  MovieType videos[Max_Video];
   int totalNumMovies;
};

**** end of specification file   Movie.h *******


**** start of implementation file Movie.cpp *******
#include"Movie.h"//preprocessor directives
#include <iostream>
#include <iomanip>

using namespace std;

//********************************************************************
int Movie::openDBFile()
{
   FILE* movieDBFile;
   if ((movieDBFile = fopen("Montgomery6.bin", "rb")) == NULL) {
       cout << "\nCannot open file: Montgomery6.bin\n";
       return 1;
   } else {
       fread(videos, sizeof videos, 1, movieDBFile);
       fread(&totalNumMovies, sizeof totalNumMovies, 1, movieDBFile);
       return 0;
   }
}
//********************************************************************
void Movie::saveDBFile()
{
   FILE* movieDBFile;
   if ((movieDBFile=fopen("Montgomery6.bin", "wb")) == NULL) {
       cout << "Cannot open file" << endl;
   } else {
       //Open our binary file for writing
       fwrite(videos, sizeof videos, 1, movieDBFile);
       fwrite(&totalNumMovies, sizeof totalNumMovies, 1, movieDBFile);
       fclose(movieDBFile);
   }
}
//********************************************************************
void Movie::printMainMenu() const
{
   cout << "\n_______________________\n";
   cout << "Video Management System\n";
   cout << "_______________________\n";
   cout << "A.  Add a Movie\n";
   cout << "D.  Delete a Movie\n";
   cout << "L.  List all Movies\n";
   cout << "S.  Search for a Movie\n";
   cout << "-.  Mark movie as rented\n";
   cout << "+.  Mark movie as returned\n";
   cout << "Q.  Quit\n";
   cout << "_______________________\n";
   cout << "Enter your choice:  ";
}
//********************************************************************
void Movie::chooseGenre(char genre[12])
{
   char answer = '0';
   char valid = '1';

   do {
       cout << "\nChoose a movie genre\n";
       cout << "--------------------\n";
       cout << "1.  Action\n";
       cout << "2.  Classics\n";
       cout << "3.  Comedy\n";
       cout << "4.  Drama\n";
       cout << "5.  Family\n";
       cout << "6.  Foreign\n";
       cout << "7.  Horror\n";
       cout << "8.  Romance\n";
       cout << "9.  SciFi\n";
       cout << "Enter the number of your choice:  ";

       cin >> answer;

       switch(answer) {
           case '1' : strcpy(genre,"Action"); valid = '0'; break;
           case '2' : strcpy(genre,"Classics"); valid = '0'; break;
           case '3' : strcpy(genre,"Comedy"); valid = '0'; break;
           case '4' : strcpy(genre,"Drama"); valid = '0'; break;
           case '5' : strcpy(genre,"Family"); valid = '0'; break;
           case '6' : strcpy(genre,"Foreign"); valid = '0'; break;
           case '7' : strcpy(genre,"Horror"); valid = '0'; break;
           case '8' : strcpy(genre,"Romance"); valid = '0'; break;^M
           case '9' : strcpy(genre,"SciFi"); valid = '0'; break;
           default  : cout << "\n\nInvalid choice.  Please try again.\n"; break;
       }
   } while ( valid != '0' );
}
//********************************************************************
void Movie::addMovie()
{
   char title[80];
   char genre[12];
   char moviestar1[30];
   char moviestar2[30];
   int totalNumCopies;
   char field[10] = "title";
   char valid='1';
   int results[Max_Video]; //array to store search results
   int count=0; //number of results returned by search


   while (valid != '0') {
       system("tput clear");
       cin.clear();
       cin.ignore(100,'\n');
       cout << "Enter movie title to add:  ";
       cin.getline(title,80);

       searchMovies(field, title, results, count);

       if (count > 0) {
           cout << "\n\n" << title << " already exists in the movie database.\n\n";
           break;
       }

       chooseGenre(genre);

       cout << "Enter the name of the movie's star:  ";
       cin.clear();  //flush the buffer
       cin.ignore(100,'\n');
       cin.getline(moviestar1,30);

       cout << "Enter the name of a second star or <ENTER> to skip:  ";
       cin.getline(moviestar2,30);

       cout << "Enter total number of copies:  ";
       cin >> totalNumCopies;
       while (!cin) {
           cout << "\nEnter only numbers please.\n\n";
           cin.clear();
           cin.ignore(100,'\n');
           cout << "Enter total number of copies:  ";
           cin >> totalNumCopies;
       }

       //save the values into our videos array
       strcpy(videos[totalNumMovies].title,title);
       strcpy(videos[totalNumMovies].genre,genre);
       strcpy(videos[totalNumMovies].moviestar1, moviestar1);
       strcpy(videos[totalNumMovies].moviestar2, moviestar2);
       videos[totalNumMovies].totalNumCopies = totalNumCopies;
       videos[totalNumMovies].numAvailCopies = totalNumCopies;


       totalNumMovies++;   // increment after adding a movie
       cout << "\n" << title << " added to the movie database.\n\n";
       valid = '0';
   }
}
//********************************************************************
void Movie::delMovie()
{
   char field[10]= "title";
   char title[80];
   int results[Max_Video];
   char valid='1';
   int count=0;



   while (valid != '0') {
       system("tput clear");
       if (totalNumMovies == 0) {
           cout << "\n\nNo movies in the database.  Nothing to delete.\n\n";
           break;
       }
       cout << "Enter movie title to delete:  ";
       cin.clear();
       cin.ignore(100,'\n');
       cin.getline(title,80);

       searchMovies(field, title, results, count);

       if (count > 0) {
           videos[results[0]]=videos[totalNumMovies - 1];
           totalNumMovies--;
           cout << "\n" << title << " deleted from the movie database.\n\n";
           valid='0';
       } else {
           cout << "\n" << title << " not found in the movie database.\n\n";
           break;
       }
   }
}
//********************************************************************
void Movie::userSearch()
{
   char field[10];
   char searchPattern[80];
   int results[100];
   char genre[12];
   char answer;
   char valid='1';
   int count=0;
   int i;
   do {
       cout << "\n\n-----------\n";
       cout << "Search Menu\n";
       cout << "-----------\n";
       cout << "Do you want to search:\n\n";
       cout << "1.  By Movie Title\n";
       cout << "2.  By Actor/Actress\n";
       cout << "3.  By Genre\n\n";
       cout << "Enter the number of your choice:  ";
       cin >> answer;
       if ((answer == '1') || (answer == '2') || (answer == '3')) {
           valid = '0';
       }
   } while (valid != '0');

   if (answer == '1') {
       cout << "\n\nEnter a movie title:  ";
       cin.clear();     // clear buffer to allow for input
       cin.ignore(100,'\n');
       cin.getline(searchPattern,80);
       strcpy(field,"title");
   } else if (answer == '2') {
       cout << "\n\nEnter the name of an Actor/Actress:  ";
       cin.clear();
       cin.ignore(100,'\n');
       cin.getline(searchPattern,80);
       strcpy(field,"moviestar");
   } else if (answer == '3') {
       chooseGenre(genre);^M
       strcpy(searchPattern,genre);
       strcpy(field,"genre");^M
   }

   searchMovies(field, searchPattern, results, count);
   if (count > 0) {
       //list all elements of videos for search results
       cout << "\nSearch results for " << searchPattern << endl << endl;
       cout << setw(20) << "Movie" << setw(7) << "Genre" << setw(15) << "Star#1";
       cout << setw(15) << "Star#2" << setw(10) << "#copies" << setw(7) << "#avail" << endl;
       cout << "--------------------------------------------------------------------------\n";
       for (i=0; i<count; i++) {
           cout << setw(20) << videos[results[i]].title;
           cout << setw(7) << videos[results[i]].genre;
           cout <<  setw(15) << videos[results[i]].moviestar1;
           cout << setw(15) << videos[results[i]].moviestar2;
           cout << setw(10) << videos[results[i]].totalNumCopies;
           cout << setw(7) << videos[results[i]].numAvailCopies << endl;
       }
   } else {
       cout << "No records found matching " << searchPattern << endl;
   }
}
//********************************************************************
void Movie::searchMovies (char field[10], char searchPattern[80], int results[Max_Video], int& count)
{
   int i;
   if ( compareStrings(field,"title") == 0) {
       if (totalNumMovies > 0) {
           for (i=0; i < totalNumMovies; i++) {
               if (compareStrings(searchPattern,videos[i].title) == 0) {  //strings match - add movie to the results array
                   results[count] = i;
                   count++;
               }
           }
       }
   } else if ( compareStrings(field,"moviestar") == 0) {
       if (totalNumMovies > 0) {
           for (i=0; i < totalNumMovies; i++) {
               if (compareStrings(searchPattern,videos[i].moviestar1) == 0) {
                   results[count] = i;
                   count++;
               }
           }
           for (i=0; i < totalNumMovies; i++) {
               if (compareStrings(searchPattern,videos[i].moviestar2) == 0) {
                   results[count] = i;
                   count++;
               }
           }
       }
   } else if ( compareStrings(field,"genre") == 0) {
       if (totalNumMovies > 0) {
           for (i=0; i < totalNumMovies; i++) {
               if (compareStrings(searchPattern,videos[i].genre) == 0) {
                   results[count] = i;
                   count++;
               }
           }
       }
   }
}
//********************************************************************
void Movie::rentMovie ()
{
   char title[80];
   char field[10] = "title";
   int results[100];
   char valid='1';
   int count=0;

   while (valid != '0') {
       system("tput clear");
       cin.clear();
       cin.ignore(100,'\n');
       cout << "Enter movie title to mark as rented:  ";
       cin.getline(title,80);

       results[0]=-1;

       searchMovies(field, title, results, count);

       if (count >= 0) {
           //if copies are available mark as rented
           if (videos[results[0]].numAvailCopies != 0) {
               videos[results[0]].numAvailCopies--;
               cout << "\n" << title << " marked as rented in the movie database.\n\n";
               valid = '0';
           } else {
               cout << "\n\nAll copies already rented.  Cannot mark ";
               cout << videos[results[0]].title << " as rented.\n\n";
               break;
           }
       } else {
           cout << "\n" << title << " not found in the movie database.\n\n";
           break;
       }
   }
}
//********************************************************************
void Movie::returnMovie ()
{
   char title[80];
   char field[10] = "title";
   int results[100];
   char valid='1';
   int count=0;

   while (valid != '0') {
       system("tput clear");
       cin.clear();
       cin.ignore(100,'\n');
       cout << "Enter movie title to mark as returned:  ";
       cin.getline(title,80);

       results[0]=-1;

       searchMovies(field, title, results, count);

       if (count >= 0) {
           //if all movies are not accounted for, mark as returned
           if (videos[results[0]].numAvailCopies != videos[results[0]].totalNumCopies) {
               videos[results[0]].numAvailCopies++;
               cout << "\n" << title << " marked as returned in the movie database.\n\n";
               valid = '0';
           } else {
               cout << "\n\nAll copies already accounted for.  Cannot mark ";
               cout << videos[results[0]].title << " as returned.\n\n";
               break;
           }
       } else {
           cout << "\n" << title << " not found in the movie database.\n\n";
           break;
       }
   }
}
//********************************************************************
void Movie::listMovies() const
{
   int i;

   cout << endl << endl;
   system("tput clear");
   if (totalNumMovies > 0) {
       cout << "\nList of all movies in the database\n\n";
       cout << setw(20) << "Movie" << setw(7) << "Genre" << setw(15) << "Star#1";^M
       cout << setw(15) << "Star#2" << setw(10) << "#copies" << setw(7) << "#avail" << endl;^M
       cout << "--------------------------------------------------------------------------\n";^M
       for (i=0; i<totalNumMovies; i++) {^M
           cout << setw(20) << videos[i].title;^M
           cout << setw(7) << videos[i].genre;^M
           cout <<  setw(15) << videos[i].moviestar1;^M
           cout << setw(15) << videos[i].moviestar2;^M
           cout << setw(10) << videos[i].totalNumCopies;^M
           cout << setw(7) << videos[i].numAvailCopies << endl;^M
       }
   } else {
       cout << "There are no movies in the database.";
   }
   cout << endl << endl;
}

//********************************************************************
int Movie::compareStrings (char string1[80], char string2[80]) {
   if( strlen(string1) != strlen(string2)) return 1;
   for( int i = 0; i < strlen(string1); ++i ) {
       if( toupper(string1[i]) != toupper(string2[i]) ) return 1;
   }
   return 0;
}
**** end of implementation file   Movie.cpp *******
Avatar of Mike McCracken
Mike McCracken

If this code is as typed
I think you need a space in
#include"Movie.h"

#include "Movie.h"

mlmcc
Same thing in the Movie.cpp file.

#include   "Movie.h"

mlmcc
ASKER CERTIFIED SOLUTION
Avatar of darlingm
darlingm

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of temulus

ASKER

Those were as typed.  Good eye.  I added the spaces, but I still get the same errors.

-tem
Avatar of temulus

ASKER

You nailed it darlingm.  I really appreciate the help.  I feel better knowing that I will not have to hunt down a Windows system in order to compile my program.

Strange that my professor could not answer the question.  She must only really know Visual C++.

Please go to my original question and post a comment, so that I can give you those points as well.

https://www.experts-exchange.com/questions/20495637/undefined-reference-errors-on-compile-of-c-program-using-gcc-3-2.html

-tem
Avatar of temulus

ASKER

Once again, thanks for the help.