?
Solved

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

Posted on 2003-02-24
6
Medium Priority
?
365 Views
Last Modified: 2013-12-14
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 *******
0
Comment
Question by:temulus
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
6 Comments
 
LVL 101

Expert Comment

by:mlmcc
ID: 8013741
If this code is as typed
I think you need a space in
#include"Movie.h"

#include "Movie.h"

mlmcc
0
 
LVL 101

Expert Comment

by:mlmcc
ID: 8013763
Same thing in the Movie.cpp file.

#include   "Movie.h"

mlmcc
0
 
LVL 1

Accepted Solution

by:
darlingm earned 2000 total points
ID: 8013806
I'm fairly certain that you actually are not receiving a compilation error -- but instead a linking error.  The linker is complaining that it cannot find the object code (compiled cpp code) for those functions in Movie.cpp.
Each .cpp files is compiled into an object (.o for gcc) file, then the .o files are linked together to build your executable.
The steps you want to go through are:
g++ -c Movie-store.cpp  {this just creates Movie-store.o)}
g++ -c Movie.cpp  {this just creates Movie.o}
g++ Movie-store.o Movie.o -o Movie-store  {this just links the object files together, creating your executable Movie-store}
If this doesn't work, give me more information on your current compilation/linking commands.  Also, give me an updated output when you try to compile.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 1

Author Comment

by:temulus
ID: 8013832
Those were as typed.  Good eye.  I added the spaces, but I still get the same errors.

-tem
0
 
LVL 1

Author Comment

by:temulus
ID: 8013924
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.

http://www.experts-exchange.com/Programming/Q_20495637.html

-tem
0
 
LVL 1

Author Comment

by:temulus
ID: 8013940
Once again, thanks for the help.
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from http://seleniumhq.org Go to that link and select download selenium in the right hand column That will then direct you to their download page. From that p…
This article will inform Clients about common and important expectations from the freelancers (Experts) who are looking at your Gig.
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.
Suggested Courses

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question