1

So, I thought I was finishing up my program. I compiled it and got a bunch of LNK (2019 and 2001) errors.

I did do some research on them and a popular solution was to get rid of the code that was causing the error. This doesn't seem exactly right. I tried it, and it did not work.

This is the file that errors are branching from.

I am just looking at how do I approach to fix these errors..I have never faced LNK errors before.

The errors:

1>bankingdriver.obj : error LNK2019: unresolved external symbol "public: __thiscall Account::~Account(void)" (??1Account@@QAE@XZ) referenced in function "void __cdecl createTextFile(class std::basic_fstream > &)" (?createTextFile@@YAXAAV?$basic_fstream@DU?$char_traits@D@std@@@std@@@Z)

1>bankingdriver.obj : error LNK2019: unresolved external symbol "void __cdecl outputLine(class std::basic_ostream > &,class Account const &)" (?outputLine@@YAXAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@ABVAccount@@@Z) referenced in function "void __cdecl createTextFile(class std::basic_fstream > &)" (?createTextFile@@YAXAAV?$basic_fstream@DU?$char_traits@D@std@@@std@@@Z)

1>bankingdriver.obj : error LNK2019: unresolved external symbol "public: double __thiscall Account::getBalance(void)" (?getBalance@Account@@QAENXZ) referenced in function "void __cdecl updateRecord(class std::basic_fstream > &)" (?updateRecord@@YAXAAV?$basic_fstream@DU?$char_traits@D@std@@@std@@@Z)

1>bankingdriver.obj : error LNK2019: unresolved external symbol "public: void __thiscall Account::setAccountNumber(int)" (?setAccountNumber@Account@@QAEXH@Z) referenced in function "void __cdecl newRecord(class std::basic_fstream > &)" (?newRecord@@YAXAAV?$basic_fstream@DU?$char_traits@D@std@@@std@@@Z)

1>BankingSystem.obj : error LNK2001: unresolved external symbol "public: void __thiscall Account::setAccountNumber(int)" (?setAccountNumber@Account@@QAEXH@Z)

//banking system driver program

#include "BankingSystem.h" // Account class definition
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib> // exit function prototype
using namespace std;



int enterChoice();
void createTextFile( fstream& );
void updateRecord( fstream& );
void newRecord( fstream& );
void deleteRecord( fstream& );
void outputLine( ostream&, const Account & );
int getAccount( const char * const );

enum Choices { PRINT = 1, UPDATE, NEW, DELETE, END };
int main()
{

   // open file for reading and writing
   fstream inOutCredit( "credit.dat", ios::in | ios::out | ios::binary );

   // exit program if fstream cannot open file
   if ( !inOutCredit ) 
   {
      cerr << "File could not be opened." << endl;
      exit ( 1 );
   } // end if

   int choice; // store user choice

   // enable user to specify action
   while ( ( choice = enterChoice() ) != END ) 
   {
      switch ( choice ) 
      {
         case PRINT: // create text file from record file
            createTextFile( inOutCredit );
            break;
         case UPDATE: // update record
            updateRecord( inOutCredit );
            break;
         case NEW: // create record
            newRecord( inOutCredit );
            break;
         case DELETE: // delete existing record
            deleteRecord( inOutCredit );
            break;
         default: // display error if user does not select valid choice
            cerr << "Incorrect choice" << endl;
            break;
      } // end switch

      inOutCredit.clear(); // reset end-of-file indicator
   } // end while
} // end main

// enable user to input menu choice
int enterChoice()
{
   // display available options
    std::cout << "\nEnter your choice" << endl
      << "1 - store a formatted text file of accounts" << endl
      << "2 - called \"print.txt\" for printing" << endl
      << "3 - update an account" << endl
      << "4 - add a new account" << endl
      << "5 - delete an account" << endl
      << "6 - end program\n? ";

   int menuChoice;
   std::cin >> menuChoice; // input menu selection from user
   return menuChoice;
} // end function enterChoice

// create formatted text file for printing
void createTextFile( fstream &readFromFile )
{
   // create text file
   ofstream outPrintFile( "print.txt", ios::out );

   // exit program if ofstream cannot create file
   if ( !outPrintFile ) 
   {
      cerr << "File could not be created." << endl;
      exit( 1 );
   } // end if

   outPrintFile << left << setw( 10 ) << "Account" << setw( 16 )
      << "Last Name" << setw( 11 ) << "First Name" << right
      << setw( 10 ) << "Balance" << endl;

   // set file-position pointer to beginning of readFromFile
   readFromFile.seekg( 0 );

   // read first record from record file
    Account client;
   readFromFile.read( reinterpret_cast< char * >( &client ),
      sizeof( Account ) );

   // copy all records from record file into text file
   while ( !readFromFile.eof() ) 
   {
      // write single record to text file
      if ( client.getAccountNumber() != 0 ) // skip empty records
         outputLine( outPrintFile, client );

      // read next record from record file
      readFromFile.read( reinterpret_cast< char * >( &client ), 
         sizeof( Account ) );
   } // end while
} // end function createTextFile

// update balance in record
void updateRecord( fstream &updateFile )
{
   // obtain number of account to update
   int accountNumber = getAccount( "Enter account to update" );

   // move file-position pointer to correct record in file
   updateFile.seekg( ( accountNumber - 1 ) * sizeof( Account ) );

   // read first record from file
   Account client;
   updateFile.read( reinterpret_cast< char * >( &client ), 
      sizeof( Account ) );

   // update record
   if ( client.getAccountNumber() != 0 ) 
   {
      outputLine( cout, client ); // display the record

      // request user to specify transaction
      std::cout << "\nEnter charge (+) or payment (-): ";
      double transaction; // charge or payment
      std::cin >> transaction;

      // update record balance
      double oldBalance = client.getBalance();
      client.setBalance( oldBalance + transaction );
      outputLine( cout, client ); // display the record

      // move file-position pointer to correct record in file
      updateFile.seekp( ( accountNumber - 1 ) * sizeof( Account ) );

      // write updated record over old record in file
      updateFile.write( reinterpret_cast< const char * >( &client ), 
         sizeof( Account ) );
   } // end if
   else // display error if account does not exist
      cerr << "Account #" << accountNumber 
         << " has no information." << endl;
} // end function updateRecord

// create and insert record
void newRecord( fstream &insertInFile )
{
   // obtain number of account to create
   int accountNumber = getAccount( "Enter new account number" );

   // move file-position pointer to correct record in file
   insertInFile.seekg( ( accountNumber - 1 ) * sizeof( Account ) );

   // read record from file
   Account client;
   insertInFile.read( reinterpret_cast< char * >( &client ), 
      sizeof( Account ) );

   // create record, if record does not previously exist
   if ( client.getAccountNumber() == 0 ) 
   {
      string lastName;
      string firstName;
      double balance;

      // user enters last name, first name and balance
      std:: cout << "Enter lastname, firstname, balance\n? ";
      std::cin >> lastName;
      std::cin >> firstName;
      std::cin >> balance;

      // use values to populate account values
      client.setLastName( lastName );
      client.setFirstName( firstName );
      client.setBalance( balance );
      client.setAccountNumber( accountNumber );

      // move file-position pointer to correct record in file
      insertInFile.seekp( ( accountNumber - 1 ) * sizeof( Account ) );

      // insert record in file                       
      insertInFile.write( reinterpret_cast< const char * >( &client ),
         sizeof( Account ) );                     
   } // end if
   else // display error if account already exists
      cerr << "Account #" << accountNumber
         << " already contains information." << endl;
} // end function newRecord

// delete an existing record
void deleteRecord( fstream &deleteFromFile )
{
   // obtain number of account to delete
   int accountNumber = getAccount( "Enter account to delete" );

   // move file-position pointer to correct record in file
   deleteFromFile.seekg( ( accountNumber - 1 ) * sizeof( Account ) );

   // read record from file
   Account client;
   deleteFromFile.read( reinterpret_cast< char * >( &client ), 
      sizeof( Account ) );

   // delete record, if record exists in file
   if ( client.getAccountNumber() != 0 ) 
   {
      Account blankClient; // create blank record

      // move file-position pointer to correct record in file
      deleteFromFile.seekp( ( accountNumber - 1 ) * 
         sizeof( Account ) );

      // replace existing record with blank record
      deleteFromFile.write( 
         reinterpret_cast< const char * >( &blankClient ), 
         sizeof( Account ) );

      std::cout << "Account #" << accountNumber << " deleted.\n";
   } // end if
   else // display error if record does not exist
      cerr << "Account #" << accountNumber << " is empty.\n";
} // end deleteRecord

// display single record
void outputLine( ostream &output,Account &record )
{
   output << left << setw( 10 ) << record.getAccountNumber()
      << setw( 16 ) << record.getLastName()
      << setw( 11 ) << record.getFirstName()
      << setw( 10 ) << setprecision( 2 ) << right << fixed 
      << showpoint << record.getBalance() << endl;
} // end function outputLine

// obtain account-number value from user
int getAccount( const char * const prompt )
{
   int accountNumber;

   // obtain account-number value
   do 
   {
       std::cout << prompt << " (1 - 100): ";
       std::cin >> accountNumber;
   } while ( accountNumber < 1 || accountNumber > 100 );

   return accountNumber;
} // end function getAccount
  • did you link the BankingSystem library? in library->input options ? – fatihk Jul 18 '13 at 06:49
  • I'm sorry, but what do you mean? – user2592447 Jul 18 '13 at 06:53
  • 1
    http://msdn.microsoft.com/en-us/library/799kze2z(v=vs.80).aspx – Hitesh Vaghani Jul 18 '13 at 06:55
  • 1
    *"I did do some research on them and a popular solution was to get rid of the code that was causing the error."* - Why stop there? Just remove all of your code, I guarantee that the error will go away. – Ed S. Jul 19 '13 at 21:14
  • possible duplicate of [c++ lnk 2028, lnk 2020, lnk 2019 and lnk 2001 when importing dll](http://stackoverflow.com/questions/14280582/c-lnk-2028-lnk-2020-lnk-2019-and-lnk-2001-when-importing-dll), http://stackoverflow.com/q/16855476/62576, and about a dozen others that mention that you forgot to include the `.lib` file. – Ken White Jul 19 '13 at 22:04
  • I've checked several other LNK2019 answers, and they all seem to be special cases that don't exactly match the issue here. – Adrian McCarthy Jul 19 '13 at 23:16

3 Answers3

0

You should check the 'BankingSystem.h' and the Account class in that. There error means these function address such 'getBalance' havn't found by compiler, so you should check these function exist or not first, then you must ensure the BankingSystem.lib file had been included in your project.

bony
  • 611
  • 4
  • 7
0

These errors mean that the functions are defined, but not declared. So the compiler has seen a definition of what the functions are, but the functions have not been implemented in the project. Maybe they exist in a library, or you are missing a CPP file in the project.

cdmh
  • 3,294
  • 2
  • 26
  • 41
0

The compiler takes a source file and makes an object file. The linker takes all of the object files (and libraries) and makes an executable (or DLL). The message you're getting suggests that you either forgot to write code for those functions or you forgot to include a necessary object file or library in the link step.

This appears to be MS VC++. If you're using the command line tools (or something like NMAKE which uses the command line tools), then be aware the cl command will, by default, compile and then attempt to link the resulting file. This is fine for a quick experiment, but is rarely useful when your project spans multiple source files.

My guess is that you're just trying to compile one of your files, and cl is trying to link it for you as well. To make cl do just the compiling step use the /c option. Then, once you've compiled all your source files into object files, you can link them as a separate step with the link command and list out all the object files.

If you're using the Visual Studio IDE to build, then you need to add all of the source files to the same project.

Adrian McCarthy
  • 45,555
  • 16
  • 123
  • 175