URGENT HELP REQUIRED!!! Errors on compile...

D

dasilva109

Hi guys

I am new to C++ and need urgent help with this part of my code for a
uni coursework I have to submit by Thursday

//ClientData.h
#ifndef CLIENTDATA_H
#define CLIENTDATA_H

#include <string>
using std::string;

class ClientData
{
public:
// default ClientData constructor
inline ClientData( int = 0, string = "", string = "", string = "",
string = "" );

// accessor functions for accountNumber
void setAccountNumber( int );
int getAccountNumber() const;

// accessor functions for clientName
void setClientName( string );
string getClientName() const;

// accessor functions for clientAddress
void setClientAddress( string );
string getClientAddress() const;

//accessor functions for contactName
void setContactName( string );
string getContactName() const;

//accessor functions for clientPhone
void setClientPhone( string );
string getClientPhone() const;

private:
const int accountNumber;
const char telNumber[ 11 ];
const char clientName[ 20 ];
const char clientAddress[ 20 ];
const char contactName[ 15 ];
}; // end class ClientData

#endif

//TheClient.cpp
// This program reads a random access file sequentially, updates
// data previously written to the file, creates data to be placed
// in the file, and deletes data previously in the file.

#include "ClientData.h" // ClientData class definition

#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::fixed;
using std::ios;
using std::left;
using std::right;
using std::showpoint;

#include <fstream>
using std:fstream;
using std:stream;
using std::fstream;

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

//#include <cstdlib>



int enterChoice();
void createTextFile( fstream& );
void updateRecord( fstream& );
void newRecord( fstream& );
void deleteRecord( fstream& );
void outputLine( ostream&, const ClientData & );
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:ut );

// 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

return 0;
} // end main

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

int menuChoice;
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:ut );

// 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( 10 ) << "Client
Name" << setw( 16 )
<< "Address" << setw( 11 ) << "Contact Name" << right
<< setw( 10 ) << "Telephone No" << endl;

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

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

// 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( ClientData ) );
} // 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( ClientData ) );

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

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

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

// write updated record over old record in file
updateFile.write( reinterpret_cast< const char * >( &client ),
sizeof( ClientData ) );
} // 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( ClientData ) );

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

// create record, if record does not previously exist
if ( client.getAccountNumber() == 0 )
{
char telNumber[ 11 ];
char clientName[ 20 ];
char clientAddress[ 40 ];
char contactName[ 15 ];

// user enters last name, first name and balance
cout << "Enter clientname, address, contactname, telnumber\n? ";
cin >> setw( 20 ) >> clientName;
cin >> setw( 40 ) >> clientAddress;
cin >> setw( 15 ) >> contactName;
cin >> setw( 11 ) >> telNumber;
//cin >> balance;

// use values to populate account values
client.setClientName( clientName );
client.setClientAddress( clientAddress);
client.setContactName( contactName );
client.setClientPhone( telNumber );
client.setAccountNumber( accountNumber );

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

// insert record in file
insertInFile.write( reinterpret_cast< const char * >( &client ),
sizeof( ClientData ) );
} // 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( ClientData ) );

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

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

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

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

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, const ClientData &record )
{
output << left << setw( 10 ) << record.getAccountNumber()
<< setw( 20 ) << record.getClientName()
<< setw( 40 ) << record.getClientAddress()
<< setw( 15 ) << record.getContactName()
<< setw( 11 ) << record.getClientPhone()
<< setw( 10 ) << setprecision( 2 ) << right << fixed
<< showpoint << endl;
} // end function outputLine

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

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

return accountNumber;
} // end function getAccount

Problem:
It compiles with 0 errors & 0 warnings in MSVisual C++ 6, but when you
try and get it to build .exe, it has these errors:
Linking...
Wholesaler.obj : error LNK2005: _main already defined in TheClient.obj
TheClient.obj : error LNK2001: unresolved external symbol "public: int
__thiscall ClientData::getAccountNumber(void)const "
(?getAccountNumber@ClientData@@QBEHXZ)
TheClient.obj : error LNK2001: unresolved external symbol "public:
__thiscall ClientData::ClientData(int,class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >,class std::basic_string<char,struct
std::char_traits<cha
r>,class std::allocator<char> >,class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >,class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >)" (??0ClientData@@QAE@HV?$basic_string@DU
?$char_traits@D@std@@V?$allocator@D@2@@std@@000@Z)
TheClient.obj : error LNK2001: unresolved external symbol "public: void
__thiscall ClientData::setAccountNumber(int)"
(?setAccountNumber@ClientData@@QAEXH@Z)
TheClient.obj : error LNK2001: unresolved external symbol "public: void
__thiscall ClientData::setClientPhone(class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >)"
(?setClientPhone@ClientData@@QAEXV?$basic_string@
DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
TheClient.obj : error LNK2001: unresolved external symbol "public: void
__thiscall ClientData::setContactName(class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >)"
(?setContactName@ClientData@@QAEXV?$basic_string@
DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
TheClient.obj : error LNK2001: unresolved external symbol "public: void
__thiscall ClientData::setClientAddress(class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >)"
(?setClientAddress@ClientData@@QAEXV?$basic_str
ing@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
TheClient.obj : error LNK2001: unresolved external symbol "public: void
__thiscall ClientData::setClientName(class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >)"
(?setClientName@ClientData@@QAEXV?$basic_string@DU
?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
TheClient.obj : error LNK2001: unresolved external symbol "public:
class std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > __thiscall ClientData::getClientName(void)const
" (?getClientName@ClientData@@QBE?AV?$basic_s
tring@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
TheClient.obj : error LNK2001: unresolved external symbol "public:
class std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > __thiscall
ClientData::getClientAddress(void)const "
(?getClientAddress@ClientData@@QBE?AV?$b
asic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
TheClient.obj : error LNK2001: unresolved external symbol "public:
class std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > __thiscall ClientData::getContactName(void)const
" (?getContactName@ClientData@@QBE?AV?$basic
_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
TheClient.obj : error LNK2001: unresolved external symbol "public:
class std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > __thiscall ClientData::getClientPhone(void)const
" (?getClientPhone@ClientData@@QBE?AV?$basic
_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
TheRetailer.obj : error LNK2001: unresolved external symbol "public:
__thiscall TheClient::TheClient(char const *,char const *,char const
*)" (??0TheClient@@QAE@PBD00@Z)
TheSupplier.obj : error LNK2001: unresolved external symbol "public:
__thiscall TheClient::TheClient(char const *,char const *,char const
*)" (??0TheClient@@QAE@PBD00@Z)
Debug/WholesalerFinal.exe : fatal error LNK1120: 12 unresolved
externals
Error executing link.exe.

WholesalerFinal.exe - 15 error(s), 0 warning(s)

Scratching my head as to why, and what all that error goobledeegook
means?

Thank you in advance for your help guys.
 
V

Victor Bazarov

I am new to C++ and need urgent help with this part of my code for a
uni coursework I have to submit by Thursday
[..]

Problem:
It compiles with 0 errors & 0 warnings in MSVisual C++ 6, but when you
try and get it to build .exe, it has these errors:
Linking...
Wholesaler.obj : error LNK2005: _main already defined in TheClient.obj
[..]

You didn't post 'Wholesaler'. But don't bother, your problem is likely
that you have two 'main' functions. You only need one per program.

Now, it is possible (judging from the names of your files) that you have
a client/server system there, meaning you need two different *programs*.
In that case you might want to ask in 'microsoft.public.vc.??' how to
organize your project (and what buttons to push in VC++ to accomplish it)
Scratching my head as to why, and what all that error goobledeegook
means?

It [usually] means you screwed up somewhere. Work on the top error
first, then rebuild...

We really cannot help you much since your code compiles cleanly (as
you say).

V
 
F

F.J.K.

You didn't post 'Wholesaler'. But don't bother, your problem is likely
that you have two 'main' functions. You only need one per program.

Now, it is possible (judging from the names of your files) that you have
a client/server system there, meaning you need two different *programs*.
In that case you might want to ask in 'microsoft.public.vc.??' how to
organize your project (and what buttons to push in VC++ to accomplish it)

all the above + more:
//ClientData.h
#include <string>
using std::string;

Never ever do this, use fully qualified names in headers. The using
directives is for implementation files.
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::fixed;
using std::ios;
using std::left;
using std::right;
using std::showpoint;

just write "using namespace std;" or fully qualified names, unless
you're payed per character typed.

Now to the more serious screwups:
Two main functions and omission/wrong location of Wholesaler.cpp was
already mentioned by Victor.

Also there's a lot of nasty screwups, covered in the FAQ. Read all of:

http://www.parashift.com/c++-faq-lite/index.html

Two examples:
void setClientName( string );

should be:
void setClientName (const std::string&)

string getClientName() const;

should be:
const std::string& getClientName() const;

Theres's several of these in your code.

Even worse:
you just declared your accessor functions and never defined them.
That's where your LNK2001 errors come from:
TheClient.obj : error LNK2001: unresolved external symbol "public: int
__thiscall ClientData::getAccountNumber(void)const "

Still worse:
Your class is declared in a way, that there's no possible way you ever
had any of these functions working:
...
void setClientPhone( string );
string getClientPhone() const;
private:
const int accountNumber;
const char telNumber[ 11 ];
const char clientName[ 20 ];
const char clientAddress[ 20 ];
const char contactName[ 15 ];
...

I leave it to you to find out, what's wrong about declaring data
members as const when you have accessor functions that are to change
them.

It means you screwed up at something related to templates and also at
choosing your compiler. VC6.0 is ancient, notoriously buggy and has
horrible error messages and close to nonexistant standard conformance
in regard to templates. VC8.0 and cygwin/g++ are available for free and
much better at everything.

This code is so bad, that I really wonder, if it's not one of those:
"Find the 20 most horrible mistakes in following code." homework
assignments. In this case: Congrats, you've just suckered me into doing
it for you :p
 
D

David Harmon

On 30 Aug 2006 04:00:44 -0700 in comp.lang.c++, (e-mail address removed)
wrote,
Scratching my head as to why, and what all that error goobledeegook
means?

They mean very nearly what they say. Just ignore the extra
implementation details you don't really care about, and pick out
the important parts from each message.
Wholesaler.obj : error LNK2005: _main already defined in TheClient.obj

How much more clear could that be? You have defined main() in both
Wholesaler.cpp and TheClient.cpp. THERE CAN BE ONLY ONE!
TheClient.obj : error LNK2001: unresolved external symbol "public: int
__thiscall ClientData::getAccountNumber(void)const "
(?getAccountNumber@ClientData@@QBEHXZ)

You declared the member function ClientData::getAccountNumber(void)
but you never actually wrote it.
TheClient.obj : error LNK2001: unresolved external symbol "public:
__thiscall ClientData::ClientData(int,class

Same for this one. And so forth.
 
P

Philip Potter

F.J.K. said:
[[email protected] wrote: FJK, please don't remove attribution lines]
//ClientData.h
#include <string>
using std::string;

Never ever do this, use fully qualified names in headers. The using
directives is for implementation files.

Definitely. Using "using" in a header is an antisocial practice.
just write "using namespace std;" or fully qualified names, unless
you're payed per character typed.

The OP's style isn't the same as yours. That doesn't make him wrong.

Also there's a lot of nasty screwups, covered in the FAQ. Read all of:

http://www.parashift.com/c++-faq-lite/index.html

Especially question 27.5.

Philip
 
F

F.J.K.

Philip said:
The OP's style isn't the same as yours. That doesn't make him wrong.

I beg to differ. If the OP forgets one of about 20-30 of these useless
declarations, it makes him wrong. The question really is: Do you want
to spare you some typing (and use using) or be explicit and "on the
safe side" of namespace issues by typing out std::xyz?

The above "coding style" just gives you 30 extra possibilities to screw
up, without any benefit like expliciteness or namespace safety. It's
also a *lot* of useless code you have to skim before you can read the
real source. If it is a style it must clearly be considered bad style
IMO.

F.J.K
 
P

Phlip

The above "coding style" just gives you 30 extra possibilities to screw
up, without any benefit like expliciteness or namespace safety. It's
also a *lot* of useless code you have to skim before you can read the
real source. If it is a style it must clearly be considered bad style
IMO.

In my exalted opinion, a stack of 'using's like that represents some lost
opportunity for encapsulation. The different things which use those should
themselves be encapsulated.

Next, a dumb little io-manipulator should occur once (local to its module),
so there's no harm in just writing out << std::left << whatever.
 
P

Philip Potter

F.J.K. said:
I beg to differ. If the OP forgets one of about 20-30 of these useless
declarations, it makes him wrong. The question really is: Do you want
to spare you some typing (and use using) or be explicit and "on the
safe side" of namespace issues by typing out std::xyz?

The above "coding style" just gives you 30 extra possibilities to screw
up, without any benefit like expliciteness or namespace safety.

You could also say that *every* C++ statement is a "possibility to screw up"
because you might forget the semicolon. But in both cases, the "screwup"
will be clearly marked by an easy-to-understand compiler error.

Philip
 
F

F.J.K.

Philip said:
Next, a dumb little io-manipulator should occur once (local to its module),
so there's no harm in just writing out << std::left << whatever.

That actually should be the preferred solution. "If in doubt, write it
out." Names like left or right can be the horror to debug. Just
consider:

#include <iostream>

using namespace std;
int main() {
{
int left=1, right=2;
cout << right-left << endl;
}
// some lengthy lines, where we forget
// our local left and right are out of scope.
cout << "Left border was : " << left << endl;
cout << "Right border was: " << right << endl;
}

Similar things have happened to me and made me abandon the "using
namespace std;" directive. There's just too much in std:: I dont't use
often enough to immediately see the possible problems with my variable
names. I would be ok with "using std::cin; using std::cout;" in
functions that heavily use them, but just brute-force "using"
everything like the OP gives you no real advantage over "using
namespace std;".

As for your follow up post:
You could also say that *every* C++ statement is a "possibility to screw up"
because you might forget the semicolon. But in both cases, the "screwup"
will be clearly marked by an easy-to-understand compiler error.

Indeed, every statement is. And having 30 of these suckers around is
like crossing the the street all day, waiting for an accident to
happen. And not all semicolon errors are that "easy-to-understand".
Also every line of code becomes a liability, when you try to understand
old/foreign code. In the case of the OP, Victor for example didn't
notice the const data members, because of all those useless,
screenspace eating lines, which should be the best argument against it
;-)

Felix
 
P

Philip Potter

F.J.K. said:
Philip schrieb:

No I didn't. Check again.
That actually should be the preferred solution. "If in doubt, write it
out." Names like left or right can be the horror to debug. Just
consider:

#include <iostream>

using namespace std;
int main() {
{
int left=1, right=2;
cout << right-left << endl;
}
// some lengthy lines, where we forget
// our local left and right are out of scope.
cout << "Left border was : " << left << endl;
cout << "Right border was: " << right << endl;
}

Similar things have happened to me and made me abandon the "using
namespace std;" directive. There's just too much in std:: I dont't use
often enough to immediately see the possible problems with my variable
names. I would be ok with "using std::cin; using std::cout;" in
functions that heavily use them, but just brute-force "using"
everything like the OP gives you no real advantage over "using
namespace std;".

I think we agree more than we disagree here. "using namespace std;" is bad,
writing things out completely is good. I think our only difference is
whether we find 30 using-declarations or 1 using-directive more abhorrent.
Personally I think using-declarations are better, but should be limited to
the scope where they are used.
As for your follow up post:

Again, I only made 1 reply.

Philip
 
F

F.J.K.

Philip said:
No I didn't. Check again.
.. snip

Again, I only made 1 reply.

Philip

My apologies, I got confused with the similarity of the words Phlip and
Philip. I'm new to newsgroups and not used to have to take that much
care in quoting, sorry. Will do in the future,

Felix
 
F

F.J.K.

Philip said:
I think we agree more than we disagree here. "using namespace std;" is bad,
writing things out completely is good. I think our only difference is
whether we find 30 using-declarations or 1 using-directive more abhorrent.
Personally I think using-declarations are better, but should be limited to
the scope where they are used.

And now we don't disagree anymore at all, because you convinced me to
use scoped using directives, if any ;-) For some reason I never
considered this before :-/

Thnx, Felix
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top