one or more multiply defined symbols found

Started by
8 comments, last by Alpha_ProgDes 21 years, 4 months ago
this is my header file...
  
#ifndef MEMBERLIST_H
#define MEMBERLIST_H

// membership database record structure type definition

struct MemberData {
	int memberNumber;	// membership number

	char lastName[20];	
	char firstName[20];
	// bitfield variables	

	unsigned duesPaid : 1; // dues status 1 = paid, 0 = not paid

	unsigned studentType : 1; // membership categories

	unsigned associateType : 1;
	unsigned fullType : 1;
	unsigned lifeType : 1;
};

// alias for struct MemberData type = Member

typedef struct MemberData Member; 
Member members = { 0, "", "", 1, 1, 0, 0, 0 };
Member *listOfMembers;

static int numOfMembers = 0;
static int sizeOfList = 0;

// symbolic constants

#define DEFAULT_DB_SIZE   5	// default size (# of records) of database array
#define MAX_DB_SIZE      50	// maximum size of database array
#define RESIZE_PADDING   10	// additonal # of records added during resize
#define TRUE 1
#define FALSE 0


/*Create a new member database
This option allows the user to designate the size, not to exceed MAX_DB_SIZE, a default size represented by DEFAULT_DB_SIZE. Use reasonable numbers like 50 and 5 for development and testing.*/

void NewDatabase(FILE *nFptr, char *filename);

/*b.Open an existing member database from file. This option opens a file and reads in data records. The number of member records
is stored in the member number field of the first record.*/

void ExistingDataBase (FILE *eFptr, const char comLineArg []);

/*c. Add member records to a database. Member records are added by appending, i.e. by adding at the end).*/
void AddMember(FILE *eFptr);

/*d. 	Search for a member record by either last name or member number. Display the record data if found or an appropriate message if it does not exist.*/

void SearchForMember(FILE *eFptr);

/*e. View the member records in the open database, i.e. print the member
records to the screen.*/

void PrintMemberList(FILE *eFptr);

/*f. Save a database to a file.*/
void SaveDataBase(FILE *eFptr);


/*g. Enter the name of the input database file on the command line, e.g.:
	C:\DataBase\asmt4.exe members.dat*/
char * CommandLine ();


/*h. Exit the database management system application*/
void StartDatabase();


void ResizeDatabase(FILE *eFptr);

#endif
  
and this is the implementation
  
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "MemberList.h"


void NewDatabase(FILE *nFptr, char *filename)
{
   char numbers[3];
   int number = 0;
   int dbSize = 0;
   char choice = ''\0'';
   if ( (nFptr = fopen(filename, "wb+")) == NULL){
      printf("File did not open.");
      return;
   }

   printf("Would you like to go with the default size or a custom size database?\n\n");
   printf("Press (D)efault or (C)ustom\n.");
   if (choice == ''D'' || choice == ''d'')
   {
      dbSize = DEFAULT_DB_SIZE;
      listOfMembers = (Member*)malloc(dbSize * sizeof(struct MemberData));
   }
   else
   {
      gets(numbers);
      dbSize = atoi(numbers);

      while (dbSize > MAX_DB_SIZE){
      gets(numbers);
      dbSize = atoi(numbers);
      }
      listOfMembers = (Member*)malloc(dbSize * sizeof(struct MemberData));
   }

   fwrite(listOfMembers, sizeof(struct MemberData), dbSize, nFptr);
   listOfMembers[0].memberNumber = numOfMembers;
   strcpy(listOfMembers[0].lastName, "Database");
   strcpy(listOfMembers[0].firstName, "Log");
   listOfMembers[0].duesPaid = 0;
   listOfMembers[0].studentType = 0;
   listOfMembers[0].associateType = 0;
   listOfMembers[0].fullType = 0;
   listOfMembers[0].lifeType = 0;
   fread(&listOfMembers[0], sizeof(struct MemberData), 1, nFptr);
   fseek(nFptr, listOfMembers[0].memberNumber * sizeof(struct MemberData), SEEK_SET);
   fwrite(&listOfMembers[0], sizeof(struct MemberData), 1, nFptr);
}

/*b.	Open an existing member database from file.
This option opens a file and reads in data records. The number of member records
is stored in the member number field of the first record.*/

void ExistingDataBase (FILE *eFptr, const char comLineArg [])
{
   if ( (eFptr = fopen(comLineArg, "ab+")) == NULL){
      printf("File cannot open. Check filename and try again.\n");
      return;
   }
}

/*	c. 	Add member records to a database.
Member records are added by appending, i.e. by adding at the end).*/
void AddMember(FILE *eFptr)
{
   int acctNum;
	
	
   char number[4];
   char lName[20];
   char fName[20];
   static int memberposition = 1;
   gets(number);
   acctNum = atoi(number);
   listOfMembers[memberposition].memberNumber = acctNum;
   gets(lName);
   strcpy(listOfMembers[memberposition].lastName, lName);
   gets(fName);
   strcpy(listOfMembers[memberposition].firstName, fName);
   gets(number);
   acctNum = atoi(number);
   listOfMembers[memberposition].duesPaid = acctNum;
   gets(number);
   acctNum = atoi(number);
   listOfMembers[memberposition].studentType = acctNum;
   gets(number);
   acctNum = atoi(number);
   listOfMembers[memberposition].associateType = acctNum;
   gets(number);
   acctNum = atoi(number);
   listOfMembers[memberposition].fullType = acctNum;
   gets(number);
   acctNum = atoi(number);
   listOfMembers[memberposition].lifeType = acctNum;
   if(feof(eFptr)) {
      ResizeDatabase(eFptr);
      fread(&listOfMembers[memberposition], sizeof(struct MemberData), 1, eFptr);
      fseek(eFptr, memberposition * sizeof(struct MemberData), SEEK_SET);
      fwrite(&listOfMembers[memberposition], sizeof(struct MemberData), 1, eFptr);
   }
   else {
      fread(&listOfMembers[memberposition], sizeof(struct MemberData), 1, eFptr);
      fseek(eFptr, memberposition * sizeof(struct MemberData), SEEK_SET);
      fwrite(&listOfMembers[memberposition], sizeof(struct MemberData), 1, eFptr);
   }
   ++numOfMembers;
}
/*d. 	Search for a member record by either last name or member number.
		Display the record data if found or an appropriate message if it does not
 exist.*/

void SearchForMember(FILE *eFptr)
{
   char lname[20];
   //char fname[20];
	char numbers[3];
	char choice = ''\0'';
	int acctNum = 0;
	int pos = 1;
	printf("Would you like to search by memberNumber or lastName?\n");
   printf("Press (m)emberNumber or (l)astName");

   if (choice == ''m''){
      gets(lname);
      while (!feof(eFptr))
      { 
		 fread(&listOfMembers[pos], sizeof(struct MemberData), 1, eFptr);
         strcmp(lname, listOfMembers[pos].lastName);
         if (strcmp(lname, listOfMembers[pos].lastName) == 0){
            printf ("%-6s%-16s-%11s%10.2f\n", "Acct", "Last Name",
                  "First Name", "Balance");
            printf ("%-6s%-16s-%11s%10.2f\n", listOfMembers[pos].memberNumber,
                  listOfMembers[pos].lastName, listOfMembers[pos].firstName);
            break;
         }
		 ++pos;
      }
   }
   else {
      gets(numbers);
      acctNum = atoi(numbers);
      while (!feof(eFptr))
      {
         fread(&listOfMembers[pos], sizeof(struct MemberData), 1, eFptr);
      //strcmp(lname, members.lastName);
         if (listOfMembers[pos].memberNumber == acctNum){
            printf ("%-6s%-16s-%11s%10.2f\n", "Acct", "Last Name",
                  "First Name", "Balance");
            printf ("%-6s%-16s-%11s%10.2f\n", listOfMembers[pos].memberNumber,
                  listOfMembers[pos].lastName, listOfMembers[pos].firstName);
         break;
         }
      }
   }
}
/*e. 	View the member records in the open database, i.e. print the member
records to the screen.*/

void PrintMemberList(FILE *eFptr)
{
   int pos = 1;
   printf ("%-6s%-16s-%11s%10.2f\n", "Acct", "Last Name", "First Name", "Balance");
   while (!feof(eFptr)){
      
	  fread(&listOfMembers[pos], sizeof(struct MemberData), 1, eFptr);
      if(listOfMembers[pos].memberNumber != 0)
      printf ("%-6s%-16s-%11s%10.2f\n", listOfMembers[pos].memberNumber,
               listOfMembers[pos].lastName, listOfMembers[pos].firstName);
	  ++pos;
   }
}

/*f. 	Save a database to a file.*/

void SaveDataBase(FILE *eFptr)
{
   FILE *SaveFile;
   if ( (SaveFile = fopen("savefile.txt", "w")) == NULL){
      printf("File did not open.\n");
      return;
   }
   else {
      rewind (eFptr);
      fprintf(eFptr, "-6s&-16s%-11s%10.2f\n", "Acct", "Last Name", "First Name",
                      "Balance");
      while (!feof(eFptr)){
         fread(&listOfMembers, sizeof(struct MemberData), 1, eFptr);
         if (members.memberNumber != 0)
            fprintf(SaveFile, "%-6d%-16s%-11s%10.2f\n", members.memberNumber,
                           members.lastName, members.firstName);
      }
      fclose(SaveFile);
   }
}

/*g. 	Enter the name of the input database file on the command line, e.g.:
	C:\DataBase\asmt4.exe members.dat*/

char * CommandLine ()
{
   
   char *argv = NULL;
   gets (argv);
   return (argv);
   
}

	/*h. 	Exit the database management system application*/
void StartDatabase()
{
   printf("Choose from the options below.\n\n");
   printf("Open New/Existing File - Press 1\n");
   printf("Add New Member - Press 2\n");
   printf("Delete a Member - Press 3\n");
   printf("Search for a Member - Press 4\n");
   printf("View Members Onscreen - Press 5\n");
   printf("Save to File - Press 6\n");
   printf("End Database Program - Press 7\n");
}

void ResizeDatabase(FILE *eFptr)
{
   int dbSize = 0;

      if (sizeOfList == MAX_DB_SIZE)
         printf("Sorry, database is full.\n");
      else if ((sizeOfList + RESIZE_PADDING) > MAX_DB_SIZE){
         dbSize = MAX_DB_SIZE - sizeOfList;
         listOfMembers = (Member*)realloc(listOfMembers, dbSize * sizeof(struct MemberData));
      }
      else {
      dbSize = RESIZE_PADDING;
      listOfMembers = (Member*)realloc(listOfMembers, dbSize * sizeof(struct MemberData));
      }
   sizeOfList += dbSize;

}
  
and this is my main
  
#include <stdio.h>
#include <string.h>
#include "MemberList.h"

int main(int argc, char *argv[])
{
	FILE *DataFile;
	
	strcpy(argv[1], CommandLine());
	NewDatabase (DataFile, argv[1]); 
  return 0;
}
  
and this is my error: Database_Main.obj : error LNK2005: "struct MemberData members" (?members@@3UMemberData@@A) already defined in MemberList.obj Database_Main.obj : error LNK2005: "struct MemberData * listOfMembers" (?listOfMembers@@3PAUMemberData@@A) already defined in MemberList.obj Debug/database.exe : fatal error LNK1169: one or more multiply defined symbols found Error executing link.exe. database.exe - 3 error(s), 0 warning(s) what am i doing wrong? i don''t understand why it''s doing that... can anyone please. and yes it''s C not C++. thank you.

Beginner in Game Development?  Read here. And read here.

 

Advertisement
Each translation unit including your "MemberList.h" header gets a copy of the members, listOfMembers, numOfMembers and sizeOfList variables.

This is fine for the later two which are declared static, which means that the numOfMembers variable that MemberList.c sees isn''t the same variable as that which main.c sees (which is probably not what you want).

However, for the former two, the linker sees two symbols (here, variables, but could be functions) with the same name in two separate object modules and aborts, reporting the name collision.

The solution is to declare the variable extern in the header file (which is similar to having a function prototype) and to define it in a single source file (similar to having a function body).

See the ''Header file'' link in my signature.



[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | Free C++ IDE. ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Boost C++ Lib ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Read the error messages closely. It''s telling you that two variables exist in two object files.

Member members = { 0, "", "", 1, 1, 0, 0, 0 };
Member *listOfMembers;

You''ve defined these in the header, which is included in both your c files. That means you get a copy of each variable with the same name in both obj files.

Fix this by using the extern keyword or not using globals. And get a book on C.

Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions
I wanted to say thank you Fruny for your constructive answer. I really appreciate it.

Beginner in Game Development?  Read here. And read here.

 

quote:Original post by Alpha_ProgDes
I wanted to say thank you Fruny for your constructive answer. I really appreciate it.


Er... this comment looks as though you''re trying to be clever and, possibly, even scathing. Siaspete''s answer was fine. Not at all rude (as you''ve commented in another thread), and he gave you the right answer.

I don''t mean to be offensive to the young in general but - Alpha_ProgDes, how old are you?

If you pull that kind of trick too many times people will stop answering your questions as they get to know you.
Looking back on my answer I can see how someone might have taken it the wrong way. Normally when I answer here I''m on my lunch break and don''t really have the time to flesh out what I say as much as I''d like. Because of this I tend to be really terse.

Thanks for your post petewood. I didn''t take offence at his reply though, he just didn''t know that I didn''t have the time to answer properly and in full. I''m an okay guy, honest guv :-)

Wow I think I took longer over this post than any other in the last few months!

Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions
I think he took offense at the "Get a book on C" part .
==========================================In a team, you either lead, follow or GET OUT OF THE WAY.
If he''s offended by the idea of geting himself a book on C then he can get me one instead. Mine''s 250 miles away and out of date.

''Get me a book on C''

Fortunately I have all the books on C++ that I desire.
hello.
just so you know, i''m well over the legal age (21).
anyway, siaspete i do appreciate the answer and the fact you took the time to answer it. as Nuffsaid pointed out i was a little offended by the "get a book on C". I do have one and that was what i was using at the time. (C How To Program by Deitel & Deitel) I guess I took that the wrong way since it seemed he assumed i didn''t have one and i was looking all through my book for an answer, but didn''t find one. So anyway there are hopefully no hard feelings, siaspete.

again thank you for responding and next time i''ll be more tactful and less hot-headed when replying

Peace!!

Beginner in Game Development?  Read here. And read here.

 

okay, nicely done

peace and goodwill

This topic is closed to new replies.

Advertisement