#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    17
    Rep Power
    0

    array of pointers to structures


    Ok, I am trying to figure this out. I know this can be done in alot easier manner but I need to know how to do this with pointers instead. we were suppose to make a program that creates an array of pointers to structures. The array needs to be initialized for 10 elements, (I only used two for fast compiling and testing), pass the array to a function called processarray(). For each element in processarray(), pass the structure to calculatesalary() which will calculate the salary and store it into the salary field. Then output it in a formatted output. I can get everything to work but once I try to make pointers out of it, it tells me that I'm not using pointers.

    When i setup the array:

    emp *employee;
    employee = new emp[2];

    how do I now use that as a pointer to use for inputing my data and then calling it from the functions. I've been fighting with everything I can find online and in books and everytime I find something that says "how to use arrays of pointers to structures" it all says setup the array like above then use the dot notation to call it. i.e

    cin >> employee[i].fname;

    but we need to use:
    cin >> employee[i]->fname;

    If anyone out there can understand my ramblings and help me out I will forever be in your dept, or at least untill I have another problem.



    #include <iostream.h>
    #include <string.h>
    #include <math.h>
    #include <iomanip.h>
    #include <fstream.h>

    using namespace std;

    /*
    Setup the structure that holds all the variables that will be used and set it up as an array so multiple records can be accessed/recorded.
    */
    struct emp{
    char fname[2];
    char lname[10];
    double years;
    double payrate;
    double salary;
    };


    //initialize the global variables that will be used in processarray() and main.
    int arraysize,i=0;

    /*
    declare the two funtion prototypes for the functions processarray()
    and calculatearray().
    */
    double calculatesalary(double, double);
    void processarray(struct emp *);

    int main()
    {

    struct emp employee[10];


    //warning message
    cout << "\n*-------------------------------------*\n";
    cout << "Enter Ctrl + C to exit the program at any\n";
    cout << "time, but all inputed data will be lost.\n";
    cout << "*-------------------------------------*\n\n";

    //Start of input loop for inputing all records.
    for(i=0;i<2;i++)
    {
    //Enter the first name of the person
    cout << "\nEnter First Initial: ";
    cin >> employee[i].fname;

    //Enter the last name of the person
    cout << "Enter Last Name (Max 10 characters): ";
    cin >> employee[i].lname;

    //Enter the persons total years of service.
    cout << "Enter Years of Service: ";
    cin >> employee[i].years;

    //Enter the persons hourly wage.
    cout << "Enter Your Hourly Wage: ";
    cin >> employee[i].payrate;

    arraysize = i;
    }
    //call funtion processarray() into main and use.
    processarray(employee);


    //output the number of structs used and formated screen output
    cout << "\n\nYou have entered " << arraysize+1<< " records\n";
    cout <<"\n\nSALARY CALCULATION\n\n\n";
    cout <<"Name\t\tPayrate\t\tYears of service\tSalary\n\n";

    //for loop to display the inputed values
    for(i=0;i<=arraysize;i++)
    {
    cout << employee[i].fname << ". " << employee[i].lname << "\t"
    << employee[i].payrate << "\t\t" << employee[i].years << "\t\t\t"
    << employee[i].salary << endl;
    }

    return 0;
    }


    double calculatesalary(double x, double y)
    {
    /*
    calculation to find total yearly salary based from y input then return the
    value of x * y.
    */
    //y = y * 40 * 52;
    return (x * y);
    }


    void processarray(struct emp *employee)
    {

    /*
    calculate salary by passing the values entered for year and
    payrate to the function calculatesalary().
    */
    for(int j =0; j <= i; j++)
    {
    employee[j].salary =
    calculatesalary(employee[j].years,employee[j].payrate);
    }
    }





    This code compiles and does work. I just can't figure out the pointer notation.
    Last edited by jfmills; July 24th, 2003 at 04:16 PM.
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,223
    Rep Power
    2222
    I didn't read it that way at first, but you have an array of structs already and you need to convert the code you listed over to dealing with an array of pointers.

    First, I advise that you use code tags or php tags to preserve indentation -- quote this reply to see the example below. They're almost exactly like HTML tags, only they use square brackets and there are fewer of them.

    You really do need to learn the notation for pointers to structs, since most of the structs that you'd pass to functions would be a pointer to that struct -- to avoid a lot of data having to be copied onto the stack, which you could overrun if the data is large enough.

    You were being given good skinny in that department. You access a field in an actual struct with the dot; e.g.:
    emp.years = 4;

    But if you have a pointer, pEmp, then you would write that as:
    pEmp->years = 4;

    If you mess up and forget to use -> , the compiler should catch it and give you an error for differing levels of indirection.

    What's really important, though is that you declare your data correctly:
    Code:
    // you originally wrote:
    emp *employee;  // pointer to emp, which means an array of emp structs
    employee = new emp[2];  // actually creating the array of two structs
    
    // you want a pointer to a pointer, which is an array of pointers:
    emp **pEmp;    // an array of pointers
    pEmp = new (emp*)[2];  // create the array of two pointers
    
    // though I'd prefer a more standard notation, 
    //     especially if we already know the number of elements in the array
    emp *pEmp2[2];  // same thing, pretty much, but much easier to read and to understand
    
    // And you still need to initialize those pointers:
    pEmp[0] = new emp;
    pEmp[1] = new emp;
    
    // and referencing would be as you'd expect:
    pEmp[1]->years = 4;
    BTW, in C++, you do not need to repeatedly use the struct keyword every time you use a struct. Just use it once in the declaration:
    Code:
    #include <iostream.h> 
    #include <string.h> 
    #include <math.h> 
    #include <iomanip.h> 
    #include <fstream.h> 
    
    using namespace std; 
    
    /* 
    Setup the structure that holds all the variables that will be 
    used and set it up as an array so multiple records can be accessed/recorded. 
    */ 
    struct emp
    { 
        char fname[2]; 
        char lname[10]; 
        double years; 
        double payrate; 
        double salary; 
    }; 
    
    
    //initialize the global variables that will be used in processarray() and main. 
    int arraysize,i=0; 
    
    /* 
    declare the two funtion prototypes for the functions processarray() 
    and calculatearray(). 
    */ 
    double calculatesalary(double, double); 
    void processarray(emp *); 
    
    int main() 
    { 
    
        emp employee[10]; 
    
    // etc ...
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    17
    Rep Power
    0
    I was able to dig up some more info and get it to work on a windows machine. But it gives me a segmentation fault when I enter the first initial when it asks for it on a Linux machine (the one its suppose to work on). It gives no compile errors on the linux box either. I know there running RH but I couldn't tell you if its 7.3 or 8.0. Here is the modifiied code. Can anyone see something that a linux box would error out on when running that a windows machine wouldn't? I previewed the post with quotes and it wont preserve my indentations. hmm???

    #include <iostream.h>
    #include <iomanip.h>
    #include <string.h>


    using namespace std;

    /*
    Setup the structure that holds all the variables that will be used and set it
    up as an array so multiple records can be accessed/recorded.
    */
    struct emp{
    char fname;
    char lname;
    double years;
    double payrate;
    double salary;
    };


    //initialize the global variables that will be used in processarray() and main.
    int arraysize,i=0;

    /*
    declare the two funtion prototypes for the functions processarray()
    and calculatearray().
    */
    double calculatesalary(double, double);
    void processarray(struct emp *);

    int main()
    {

    struct emp *employee[2];
    struct emp emparray[2];
    employee[0] = &emparray[0];

    for (int j = 0; j < 10; j++)
    {
    //employee[j] = &emparray[j];
    //strcpy(emparray[j].fname," ");
    //strcpy(emparray[j].lname," ");
    emparray[j].payrate = 0;
    emparray[j].salary = 0;
    emparray[j].years = 0;
    }


    //warning message
    cout << "\n*-------------------------------------*\n";
    cout << "Enter Ctrl + C to exit the program at any\n";
    cout << "time, but all inputed data will be lost.\n";
    cout << "*-------------------------------------*\n\n";

    //Start of input loop for inputing all records.
    for(i=0;i<2;i++)
    {
    //Enter the first name of the person
    cout << "\nEnter First Initial: ";
    getline(cin,employee[i]->fname);

    //Enter the last name of the person
    cout << "Enter Last Name (Max 10 characters): ";
    cin >> employee[i]->lname;

    //Enter the persons total years of service.
    cout << "Enter Years of Service: ";
    cin >> employee[i]->years;

    //Enter the persons hourly wage.
    cout << "Enter Your Hourly Wage: ";
    cin >> employee[i]->payrate;

    arraysize = i;
    }
    //call funtion processarray() into main and use.
    processarray(emparray);


    //output the number of structs used and formated screen output
    cout << "\n\nYou have entered " << arraysize+1<< " records\n";
    cout <<"\n\nSALARY CALCULATION\n\n\n";
    cout <<"Name\t\tPayrate\t\tYears of service\tSalary\n\n";

    //for loop to display the inputed values
    for(i=0;i<=arraysize;i++)
    {


    cout << employee[i]->fname << ". " << employee[i]->lname << "\t"
    << employee[i]->payrate << "\t\t" << employee[i]->years << "\t\t\t"
    << employee[i]->salary << endl;
    }
    return 0;
    }


    double calculatesalary(double x, double y)
    {
    /*
    calculation to find total yearly salary based from y input then return the
    value of x * y.
    */
    //y = y * 40 * 52;
    return (x * y);
    }


    void processarray(struct emp *employee)
    {

    /*
    calculate salary by passing the values entered for year and
    payrate to the function calculatesalary().
    */
    for(int h =0; h <= i; h++)
    {
    employee->salary =
    calculatesalary(employee->years,employee->payrate);
    employee++;
    }
    }
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,223
    Rep Power
    2222
    Originally posted by jfmills
    I previewed the post with quotes and it wont preserve my indentations. hmm???
    Replying to my message by clicking on the quote button would have placed my message within quote tags. It would also have displayed the code tags I used to display the code -- which is also why I used code tags on the sample declarations if though it was not necessary, just to provide an example for you.

    Use the keyword "code" instead of "quote" within the tags and it will preserve your indentation. And if you use "php" tags, then it will also syntax-highlight your code with different color text. You can also experiment with a particular tag, submit the message, and then edit it if the tag didn't behave as you expected.
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,223
    Rep Power
    2222
    Originally posted by jfmills
    I was able to dig up some more info and get it to work on a windows machine. But it gives me a segmentation fault when I enter the first initial when it asks for it on a Linux machine (the one its suppose to work on). It gives no compile errors on the linux box either. I know there running RH but I couldn't tell you if its 7.3 or 8.0. Here is the modifiied code. Can anyone see something that a linux box would error out on when running that a windows machine wouldn't?
    One obvious problem I see is that you did not initialize the pointer, employee[1]. I don't know why it runs on Windows but not on Linux, unless in Windows the garbage in the uninitialized pointer employee[1] just happened to be an address within the program's memory space.

    Be sure that you initialize both pointers and see if that works.

    Also, just in case it also involves something unexpected with getline(), did your original program also work under Linux?


    [i]I know there running RH but I couldn't tell you if its 7.3 or 8.0.[/B]
    At the log-in prompt, the version is displayed. If you have it running a GUI instead, you can telnet in (eg, on the machine, open a terminal window and the command "telnet localhost") and the version is displayed in that login prompt.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    17
    Rep Power
    0
    I saw the post after I fixed my problem. I did a DUH, and forgot to initialize. I was comment things out and forgot to uncomment them. Don't ask.

    Now I have everything working like its suppose to. Now I want to add in a few things that wern't required. A bit of error checking.

    I did some searching and found a way to loop the cin on the numbers to only accept numbers. But I'm having a hard time finding anything on checking for input char size. I have my char array like this(not exactly like in the code above but you get the idea).
    PHP Code:
    char buffer[10]; 
    now what I want to do is check to make sure that only that amount of characters was entered. If you enter any more than the 10 then it will give garbage out to the screen. I guess I'm looking for the wrong thing when trying to find examples of how this could be done.

    I figured out the number checking to make sure that only numbers above 0 and no char are entered. That one seemed alot easier to do.
    PHP Code:
    do
    {
         
    cout << "Enter Years of Service: ";          
         
    cin.clear();
         
    cin.ignore(INT_MAX,'\n');

    }while(!(
    cin >> employee[i]->years)||(employee[i]->years 0)); 
    Thanks again for all the info and help.
  12. #7
  13. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,223
    Rep Power
    2222
    Originally posted by jfmills
    I saw the post after I fixed my problem. I did a DUH, and forgot to initialize. I was comment things out and forgot to uncomment them. Don't ask.
    Been there. Done even worse. Why do you think it is that the most experienced programmers seem to know exactly what kind of stupid mistakes to look for? Maybe because they had made the same mistakes themselves?

    Originally posted by jfmills
    now what I want to do is check to make sure that only that amount of characters was entered. If you enter any more than the 10 then it will give garbage out to the screen. I guess I'm looking for the wrong thing when trying to find examples of how this could be done.
    My usual approach is to have an input buffer that is more than adequately large enough (say 80 to 100 bytes, or whatever seems more than reasonable), then copy out of that buffer into the target string. That way, I won't overflow during input and I'll have the string length if I new the target string on-the-fly.

    Another approach would be to limit the input buffer size in your call to getline(); from Visual C++v1.52 Help page on istream member methods:
    istream::getline

    Syntax
    istream& getline( char* pch, int nCount, char delim = '\n'_);
    istream& getline( unsigned char* puch, int nCount, char delim = '\n'_);
    istream& getline( signed char* psch, int nCount, char delim = '\n'_);

    Parameters

    pch, puch, psch -- A pointer to a character array.

    nCount -- The maximum number of characters to store, including the terminating NULL.

    delim -- The delimiter character (defaults to newline).

    This function extracts characters from the stream until either the delimiter delim is found, the limit nCount-1 is reached, or end of file is reached. The characters are stored in the specified array followed by a null terminator. If the delimiter is found, it is extracted but not stored.
    The get function, in contrast, neither extracts nor stores the delimiter.
    Last edited by dwise1_aol; July 25th, 2003 at 01:04 PM.

IMN logo majestic logo threadwatch logo seochat tools logo