Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C++ (http://www.go4expert.com/forums/cpp/)
-   -   Can not get 2 cpp, 1 h files to link (http://www.go4expert.com/forums/2-cpp-1-h-files-link-t14235/)

thekevin07 28Sep2008 06:35

Can not get 2 cpp, 1 h files to link
 
I have 3 files firstLady.cpp (holds the class firstLady_t) firstLady.h (holds prototypes) mytestproj.cpp (main class) and I cant get them to compile.


error C2059: syntax error : 'private'


what would cause this


firstLady.h
Code:

#pragma once

private:

public:
        firstLady(void);
        firstLady(char*, unsigned, unsigned, unsigned, unsigned);
        ~firstLady(void);
        const char* getName();
        unsigned getFrom(int);
        unsigned getTo(int);
        unsigned getBorn(int);
        unsigned getDied(int);
        void setName(int, char*);
        void setFrom(int, unsigned);
        void setTo(int, unsigned);
        void setBorn(int, unsigned);
        void setDied(int, unsigned);
        void printRecord(int);
        void printAll();


firstLady.cpp
Code:

#include "firstLady.h"


//dont need data[i]

//default constructor
firstLady_t(){}
       
//new constructor so we know how new ones should be defined
firstLady_t(char *n, unsigned f, unsigned t, unsigned b, unsigned d)
{
        strcpy_s(name, maxNameLen, n);
        from=f;
        to=t;
        born=b;
        died=d;
}



//assign new data
void setName(int i, char newname[maxNameLen+1])
{
        //strcpy_s(data[i]->name,newname);
}
void setFrom(int i,unsigned newfrom)
{
        data[i]->from=newfrom;
}
void setTo(int i,unsigned newto)
{
        data[i]->to=newto;
}
void setBorn(int i,unsigned newborn)
{
        data[i]->born=newborn;
}
void setDied(int i,unsigned newdied)
{
        data[i]->died=newdied;
}
/*
*  Retrieve a record (row) from the table.
*  Inputs: search-term, name-array
*  Return value: returns index of record containing search term, or -1 otherwise
*/
int getRecord(char searchTerm[])
{
        int i;
        for(i=0; i<size && strcmp(searchTerm,data[i]->name) !=0;i++);
        if(i==size)
                return -1;
        else
                return i;
}

/*
* Print one record (row) from the table
*/
//methods to do the printing
string ShowName(int i)
{
        return data[i]->name;
}
unsigned ShowFrom(int i)
{
        return data[i]->from;
}
unsigned ShowTo(int i)
{
        return data[i]->to;
}
unsigned ShowBorn(int i)
{
        return data[i]->born;
}
unsigned ShowDied(int i)
{
        return data[i]->died;
}

//show records based on return value getRecord
void printRecord(int i)
{
        cout<<endl;
        cout<<"Name: "<<ShowName(i)<<" From: "<<ShowFrom(i)<<" To: "<<ShowTo(i)<<" Born: "<<ShowBorn(i)<<" Died: "<<ShowDied(i)<<endl;
        cout<<endl;
}
/*
* prompt for user entry and return date in
* unsigned format -- mmddyyyy
*/
unsigned getDate(char* prompt)
{
    unsigned retval = 0;
    cout << "Please enter the " << prompt << "(mmddyyyy): ";
    cin.ignore(80,'\n');
    cin >> retval;
    return retval;
}

void getName(char * prompt, char retval[], int size)
{
    cout << "Please enter name: ";
    cin.get(retval, maxNameLen, '\n');
}

/* newRecord checks space and returns the index of
*  the next free row in the table, or -1 if no
*  space is available.
*  side-effect: increments size
*/
int newRecord()
{
        if(size<numPrez-1)
        {
                data[size++]=new struct firstLady_t;
                return size++;
        }
        else
        {
                return -1;
        }
}



mytestproj.cpp

Code:

#include "stdafx.h"
#include <string>
#include <iostream>
#include <sstream>
#include "firstLady.cpp"

using namespace std;

const int numPrez=43;
const int maxNameLen=80;
/*
*  Table of first ladies
*/
// This time, let's create a structure that holds a single
// row of the table.
// This statement just defines the structure and gives the
// definition a name, firstLady_t.
struct firstLady_t {
        char name[80];
        unsigned from;
        unsigned to;
        unsigned born;
        unsigned died;
        //default constructor
        firstLady_t(){}
       
        //new constructor so we know how new ones should be defined
        firstLady_t(char *n, unsigned f, unsigned t, unsigned b, unsigned d)
        {
                strcpy_s(name, maxNameLen, n);
                from=f;
                to=t;
                born=b;
                died=d;
        }
};
struct firstLady_t *data[numPrez];

int size = 0;



int _tmain(int argc, _TCHAR* argv[])
{

        data[size++]= new struct firstLady_t("Washington, Martha",4301789,3041797,6021731,5221802);
        data[size++]= new struct firstLady_t("Adams, Abigail",3041979,3041801,11111744,10281818);
        data[size++]= new struct firstLady_t("Randolph, Martha",3041801,3041809,9271772,10101836);
        data[size++]= new struct firstLady_t("Madison, Dolley",3041809,3041817,5201768,7121849);
        data[size++]= new struct firstLady_t("Monroe, Elizabeth",3041817,3041825,6301768,9231830);
        data[size++]= new struct firstLady_t("Adams, Louisa",3041825,3041829,2121775,5151852);

    char searchTerm[maxNameLen+1] = {'\0'};  // name to search for
    char choice = '\0';
    int nr = 0; // need to declare, initialize outside the case statement
    cout << "Table of U.S. First Ladies\n" << endl;

    // main loop -- either add a new entry or search for one
    while(choice != 'q')
        {
        cout << "Enter 's' to search for an entry, 'a' to add one or q to quit: " ;
        cin>>choice;
        cin.ignore(80, '\n');
        switch(choice)
                {
                        case 's':
                        case 'S':
                                int target;

                                getName("Please enter name to search for: ", searchTerm, sizeof(searchTerm));

                                if((target=getRecord(searchTerm)) == -1)
                                { 
                                        // what happens without ()?
                                    cout << "Data for " << searchTerm << " not found.  " << size << " records searched." << endl;
                                }
                                else
                                {
                                    printRecord(target);
                                }
           
                                break;
                       
                        case 'a':
                        case 'A':
                                nr = newRecord();
                                if(nr < 0)
                                {
                        cout << "No space for additonal records." << endl;
                        continue;
                    }
                    else
                                {
                        char n[maxNameLen+1];
                        // collect data for new record
                        getName("name for new entry", n, sizeof(n));
                                        data[nr]=new firstLady_t(n,getDate("From date "),getDate("To"),getDate("Born"),getDate("Died"));
                        cout << n << " successfully added." << endl;
                    }
            break;
                       
                        case 'Q':  choice = 'q';
                        case 'q':
            break;
                       
                        default: cout << choice << " is not a valid option." << endl;
        }
    }

    return 0;
}


ahamed101 28Sep2008 13:33

Re: Can not get 2 cpp, 1 h files to link
 
hi,
why do you use private and public in the header file if its not a class?... Remove the keywords from the header file... It will work...


Regards,
Ahamed.

thekevin07 28Sep2008 23:03

Re: Can not get 2 cpp, 1 h files to link
 
actually it is a class i have to convert it from a struct to a class ive spent many hrs trying to figure it out

xpi0t0s 29Sep2008 00:41

Re: Can not get 2 cpp, 1 h files to link
 
You need to wrap the class contents with class firstLady { ... };, just as you did for struct firstLady_t.

ahamed101 29Sep2008 01:27

Re: Can not get 2 cpp, 1 h files to link
 
Yes, you need to wrap it within "{" and "}" like

Code:

class firstLADY{
private:

public:
        firstLady(void);
        firstLady(char*, unsigned, unsigned, unsigned, unsigned);
        ~firstLady(void);
        const char* getName();
        unsigned getFrom(int);
        unsigned getTo(int);
        unsigned getBorn(int);
        unsigned getDied(int);
        void setName(int, char*);
        void setFrom(int, unsigned);
        void setTo(int, unsigned);
        void setBorn(int, unsigned);
        void setDied(int, unsigned);
        void printRecord(int);
        void printAll();
};

This should solve your issue...

Regards,
Ahamed

ahamed101 29Sep2008 01:28

Re: Can not get 2 cpp, 1 h files to link
 
Quote:

Originally Posted by ahamed101
Yes, you need to wrap it within "{" and "}" like

Code:

class firstLADY{
private:

public:
        firstLady(void);
        firstLady(char*, unsigned, unsigned, unsigned, unsigned);
        ~firstLady(void);
        const char* getName();
        unsigned getFrom(int);
        unsigned getTo(int);
        unsigned getBorn(int);
        unsigned getDied(int);
        void setName(int, char*);
        void setFrom(int, unsigned);
        void setTo(int, unsigned);
        void setBorn(int, unsigned);
        void setDied(int, unsigned);
        void printRecord(int);
        void printAll();
};

This should solve your issue...

Regards,
Ahamed


Since its within a class now, you need to change the function prototypes accordingly...

Regards,
Ahamed

thekevin07 29Sep2008 07:15

Re: Can not get 2 cpp, 1 h files to link
 
I'm still having trouble I've spent 3 days on this and still can't get it. It is a homework assignment but I need help and the teacher isn't responding to my mails and the experts here have helped a ton on my personal stuff. Below is the starting project. I need to convert the struct to a class. I know classes and I know structs (I think) but I'm having trouble converting them. Any code modifications and explanations would be greatly appreciated.

defines.h
Code:

#pragma once

// globals, visible to all functions
// number of presidents is used to size the table
const int numPrez = 43;
// assumes no name will be more than 79 characters long
const int maxNameLen = 79;


main cpp file module5c.cpp
Code:


#include "stdafx.h"

/*
 *  Module 5 implements a table.  The examplely version 5c <<<< data are the names, term
 *  dates, birth and death dates of US First Ladies.
 *
 *  There are four variations of this, using
 *                parallel arrays                                                (5a)
 *                an array of structures                                (5b)
 *                an array of pointers to structures        (5c)
 *                an array of ptrs to class instances        (5d)
 */



// In version 5b, moved constants to their own file, defines.h
// defines.h is #include-d by stdafx.h


// In version 5b we created a structure that holds a single
// row of the table.
// This statement, unchanged from version 5b, just defines the
// structure and gives the definition a name, firstLady_t

struct firstLady_t {
        char name[80];
        unsigned from;
        unsigned to;
        unsigned born;
        unsigned died;
        //  a default constructor
        firstLady_t(){}
        //  a constructor to initialize new-ly created structs.
        firstLady_t(char* n, unsigned f, unsigned t, unsigned b, unsigned d) {
                strcpy_s(name, maxNameLen, n);
                from = f;
                to = t;
                born = b;
                died = d;
        }
};
// Now we construct an array of pointers to structures to hold data for all of
// first ladies.  That is, we will have a single dimensional array of pointers to
// rows.  It should still be global, or we will have to pass it as a parameter to
// every function that requires it.  To maintain continuity, we leave it global.

struct firstLady_t* data[numPrez];

// size is the number of rows in the table that contain valid data.

int size = 0;
/*
* end of table.
*
*  Globals ought to be used sparingly, and probably only for const items.
*  This is a demo, and will be fixed in the final iteration.
*/

// prototypes for utillity functions defined in this file
// copied without change from the parallel array version

int getRecord(char[]);
void getName(char*, char[], int);
unsigned getDate(char*);
int newRecord();
void putRecord(int, char[],unsigned,unsigned,unsigned,unsigned);

// The accessor function prototypes are copied without change from
// the previous version.
unsigned getFrom(int);
unsigned getTo(int);
unsigned getBorn(int);
unsigned getDied(int);
void setName(int, char*);
void setFrom(int, unsigned);
void setTo(int, unsigned);
void setBorn(int, unsigned);
void setDied(int, unsigned);
void printRecord(int);
void printAll();

void printDate(unsigned);
// shouldn't need to change the main, either, since it really only "sees" the prototypes of all functions
// the sole exception is the initialization of the first six records.  Now that data[] only holds pointers
// the structures, we must explicitly allocate the space for all of the data.  We use "new" to do that.
//
// A second problem is now obvious:  how do we get the initial data into the structure?  The answer is a
// special function called a "constructor" that does that.  Two such functions, one with no parameters and
// one with 5 parameters are defined above in the declaration of struct firstLady_t.

int _tmain(int argc, _TCHAR* argv[])
{
        // just call new six times to allocate space for, and initialize, the six records
        data[size++] = new struct firstLady_t ( "Washington, Martha",4301789,3041797,6021731,5221802 );
        data[size++] = new struct firstLady_t ("Adams, Abigail",3041979,3041801,11111744,10281818);
        data[size++] = new struct firstLady_t ("Randolph, Martha",3041801,3041809,9271772,10101836);
        data[size++] = new struct firstLady_t ("Madison, Dolley",3041809,3041817,5201768,7121849);
        data[size++] = new struct firstLady_t ("Monroe, Elizabeth",3041817,3041825,6301768,9231830);
        data[size++] = new struct firstLady_t ("Adams, Louisa",3041825,3041829,2121775,5151852);
        char searchTerm[maxNameLen+1] = {'\0'};  // name to search for
        char choice = '\0';
        int nr = 0; // need to declare, initialize outside the case statement
        cout << "Table of U.S. First Ladies\n" << endl;

        // main loop -- either add a new entry or search for one
        while(choice != 'q') {
                cout << "Enter 's' to search for an entry, 'a' to add one or q to quit: " ;
                cin>>choice;
                cin.ignore(80, '\n');
                switch(choice) {
                case 's':
                case 'S':
                        int target;

                        getName("Please enter name to search for: ", searchTerm, sizeof(searchTerm));
                        if((target=getRecord(searchTerm)) == -1) {  // what happens without ()?
                                cout << "Data for " << searchTerm << " not found.  " << size << " records searched." << endl;
                        }
                        else {
                                printRecord(target);
                        }
                        break;
                case 'a':
                case 'A':
                        nr = newRecord();
                        if(nr < 0){
                                cout << "No space for additonal records." << endl;
                                continue;
                        }
                        else {
                                char n[maxNameLen+1];
                                // collect data for new record
                                getName("name for new entry", n, sizeof(n));
                                data[nr] = new firstLady_t(n,
                                        getDate("From date "),
                                        getDate("To"),
                                        getDate("Born"),
                                        getDate("Died"));

                                cout << n << " successfully added." << endl;
                        }
                        break;
                case 'Q':  choice = 'q';
                case 'q':
                        break;
                default: cout << choice << " is not a valid option." << endl;
                }
        }

        return 0;
}

// now the function definitions.  These do need changing a bit, since
// they now work with structs.

/*
/*
*  Retrieve a record (row) from the table.
*  Inputs: search-term, name-array
*  Return value: returns index of record containing search term, or -1 otherwise
*/
int getRecord(char searchTerm[]) {
        int i;
        // linear search for searchTerm.  End with success or end of table
        // need to change this line to reflect the change from array of structs to array of ptrs to structs.
        for(i =0; i < size && strcmp(searchTerm, data[i]->name) != 0 ; i++);  // changed ref. to data[i].name

        // either i < size and is the index of the desired item, or i == size
        if(i == size)
                return -1;
        else
                return i;
}

/*
*  Put a new row into the table.
*  Inputs: name-array, from-array, to-array, born-array, died-array, size, new name, new from, new to, new born, new died
*  Side-effect: new row inserted into table on success
*  Returns new table size on success, -1 if no space left in table.
*/

// never used
void putRecord(int i, char n[], unsigned f,unsigned t, unsigned b,unsigned d){
        strcpy_s(data[i]->name, maxNameLen, n);  // change all refs to data[i].
        data[i]->from = f;
        data[i]->to = t;
        data[i]->born = b;
        data[i]->died = d;
}


//  all accessors reflect change from struct to ptr-to-struct
//  as above.
/*
*  return unsigned From-date belonging to the ith record
*/
unsigned getFrom(int i ) {
        return data[i]->from;
}
/*
*  return unsigned To-date belonging to the ith record
*/
unsigned getTo(int i) {
        return data[i]->to;
}
/*
*  return unsigned Born-date belonging to the ith record
*/
unsigned getBorn(int i) {
        return data[i]->born;
}
/*
*  return unsigned Died-date belonging to the ith record
*/
unsigned getDied(int i) {
        return data[i]->died;
}
/*
* set the From-date in the ith record
*/


/*
 * insert name field into ith record
 */
void setName(int i, char* val) {
        strcpy_s(data[i]->name, maxNameLen, val);
}
void setFrom(int i, unsigned value) {
        data[i]->from = value;
}
/*
* set the To-date in the ith record
*/

void setTo(int i, unsigned value) {
        data[i]->to = value;
}
/*
* set the Born-date in the ith record
*/

void setBorn(int i, unsigned value) {
        data[i]->born = value;
}
/*
* set the Died-date in the ith record
*/

void setDied(int i, unsigned value) {
        data[i]->died = value;
}

/*
* Print one record (row) from the table
*/
void printRecord(int i) {
        // find pointer in data, then use it to
        // access the members of the struct
        struct firstLady_t *p = data[i];

        cout << "Name: " << p->name <<
                "\t From: " << p->from <<
                "\t To: " << p->to <<
                "\t Born: " << p->born <<
                "\t Died: " << p->died << endl;
}


/*
* print date in conventional format
*/
// never used
void printDate(int date) {
        int year = date%10000;
        int month = (date/10000)%100;
        int day = date/1000000;
        char *monthName[]={"January","February","March","April","May","June","July","August","September","October","November","December"};
        cout << monthName[month] << " " << day << ", " << year;
}
/*
* prompt for user entry and return date in
* unsigned format -- mmddyyyy
*/

unsigned getDate(char* prompt) {
        unsigned retval = 0;
        cout << "Please enter the " << prompt << "(mmddyyyy): ";
        cin.ignore(80,'\n');
        cin >> retval;
        return retval;
}

void getName(char * prompt, char retval[], int size) {
        cout << "Please enter name: ";
        cin.get(retval, maxNameLen, '\n');
}
/* newRecord checks space and returns the index of
*  the next free row in the table, or -1 if no
*  space is available.
*  side-effects: allocates new struct, puts its address
*  in the first available element of the array and
*  increments variable size
*/
int newRecord() {
        if(size < numPrez -1){
                data[size] = new struct firstLady_t;
                return size++;
        }
        else
                return -1;
}

stdafx.h

Code:


// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>



// TODO: reference additional headers your program requires here
#include <iostream>
#include <string.h>
using namespace std;
#include "defines.h"


xpi0t0s 29Sep2008 18:44

Re: Can not get 2 cpp, 1 h files to link
 
How do you want to convert the struct? Is it just a case of changing "struct" to "class" and retaining the same functionality, or do you want the class to have additional functionality over the struct?

If the former, class and struct are exactly the same EXCEPT that all struct members are public by default and all class members are private by default. So struct str { int x; } is equivalent to class str { public: int x; } (References to the class itself also don't need "class", so "struct firstLady_t* data[numPrez];" becomes "firstLady_t* data[numPrez];"; any other occurrences of "struct firstLady_t" become simply "firstLady_t".)

If the latter then you'll have to state what extras you want the class to have over the struct. In other words, if changing "struct firstLady_t {" to "class firstLady_t { public:" and dropping "struct" throughout (where it refers to firstLady_t) doesn't completely answer your question, why precisely?


All times are GMT +5.5. The time now is 19:39.