Linking structure variables to an dynamic array.

Well, I took my first com sci class two semesters ago and learned quite a bit, enough to know that I enjoyed programming. The following semester I enrolled in another com sci class, except this one was online. I passed the class, but I felt like I learned next to nothing.. Then summer break happened.. And yeah, now I'm really rusty on top of already feeling a bit behind.

Anyways, my first assignment is to create a dynamic array to store names and then link those names to IDs and salary. I've created the dynamic array, and now I need help on linking the IDs and salaries to the array's variables.. If anyone can point me in the right direction on how this might be done, that would be much appreciated.. Here is a copy of my current code :

#include <iostream>

using namespace std;

struct employee
{
int id;
double salary;
char dynamic[];
};


int main()
{
cout << "Enter the number of your employees." << endl;
int SIZE;
cin >> SIZE;

int *dynamic = new int[SIZE];
for (int i=0; i<SIZE; i++)
{
dynamic[i] = 0;
};

for (int i = 1; i <= SIZE; i++)
{
cout << "Enter name for employee number " << i << ": ";
cin >> dynamic[i-1];
}


}




Any help/advice/feedback would be most appreciated!
closed account (48T7M4Gy)
1
2
3
4
5
6
7
for (int i = 0; i < SIZE; i++)
    {
        dynamic[i] = i;
        
        cout << "Enter name for employee number " << ": ";
        cin >> dynamic.name;
}
Last edited on
Ahh, thank you! I totally see what I was doing wrong/missing now. I used what you posted and kept a little bit of my own code to get the perfect set up now, I think.
closed account (48T7M4Gy)
Mine just an easy stumbling blocks going on. :)
Last edited on
I would error check SIZE in case some unexpected thing is entered.

If your teacher is anything like mine, they WILL check for that, and your program could very well explode.


If you assume only numbers will be input
1
2
3
4
5
6
7
int SIZE = 0;

while (SIZE <= 0)
{
  std::cout << "Enter size: ";
  std::cin >> SIZE;
}

Which will allow only positive integers to be entered (0 being invalid). I assumed non-numeric characters would not be entered, though.

Or whatever variant of that you need to use.

If your teacher could enter non-numeric characters as well, well that's just cruel and they should stop torturing you like that. But you could check those conditions as well.

Teachers will try to break your code, so try to think of things that could go wrong. All of my teachers have always just smashed the keyboard as input to see what would happen. Many program explosions have occurred. Learn from my mistakes :D

You should also always initialize your variables to a value (usually 0). Some pedantic compilers will refuse to compile if you don't do that, and it's always good practice to initialize everything before you use it. I have my compiler set to require initialization so I never forget.
That's a really good idea! I also included

if (!(cin >> SIZE))
{
cin.clear();
cin.ignore(1000, '\n');
}

above your while loop, just in case they do enter characters.. Seems to work real well ^_^

I'll also include getline for the name too. That should proof it real well.


edit: Hmm.. The only problem with including the above it seems is that if a valid input IS entered the first time, it asks twice until the next loop starts.. Also, with getline I'm having an issue where it only grabs the second half of someones name.. I ran into this earlier with another problem and was able to solve it with cin.ignore, but that doesn't seem to be working this time.. Anyone know where I'm going wrong with my getline??

cout << "Enter name for employee number " << i << ": ";
cin >> dynamic[i-1].name;
getline(cin, dynamic[i-1].name);

Last edited on
Your problem likely lies here:
1
2
cin >> dynamic[i-1].name;
getline(cin, dynamic[i-1].name);


It's generally not advised to mix getline with cin

cin will stop reading at whitespace, so if your line is separated by spaces cin will only capture the input up to the first whitespace character, but this will leave the remainder of the input in the buffer, and your getline call on the next line will retrieve the remainder of that buffer up to the newline character, which is the second part of the name, and is assigning what is retrieved and overwriting what the line before it did.

Using just getline on the other hand will read up until the end of the line, which will include some whitespace characters (by default it will stop at the newline character, but you can set your own delimiter as well, see: http://www.cplusplus.com/reference/string/string/getline/)

dynamic.name. That includes both the first name and the last name, I am assuming? If so, just use getline and it will capture the entire line up to the newline character.


As far as being prompted twice, you can initialize SIZE to an invalid value (like -1 or something like that) and begin the loop there:
1
2
3
4
5
6
7
int SIZE = -1;
while (SIZE <= 0)
{
  //prompt in here
  //keep spinning until they give you valid input
  //but if they enter valid input the first time then it won't loop again (condition will fail at beg of loop)
}


But that's just one way to do it. If that doesn't really make sense or seems odd to you, you can always prompt once, then enter a loop if the entered input was incorrect and loop in there until they provide valid input. Both should be fine as far as functionality is concerned, just as long as you're careful to not call new with an invalid parameter.
Just on the SIZE thing - at least make it an unsigned type, possibly std::size_t . It probably won't make much difference (still have to check the value), but at least you are using a more suitable type. In future you may be able to use that type better with exceptions - catch a range error, which you couldn't do with an int for that particular negative scenario.

Thanks for the advice all :) I'm still having issues with the getline though.. I keep getting an error of : "no matching call to function getline" whenever I try to use something other than what I posted above.. Am I missing a directory or something? I've tried using sizeof(name), removing cin, adding numbers at the end, ect and every time I get that same error.. But I can't use the one I posted above, because it skips the first half of the name heh.. I tried to read your link, JayHawk, but I got a 404 error.
Last edited on
Whoops, sorry! The ')' got included in the hyperlink XD

This one should work: http://www.cplusplus.com/reference/string/string/getline/

Hmm. getline is just in the string library, so you should be good to go by using #include <string>

If you can, I really recommend using std::string. It's so much easier, and so much nicer to use than using raw character arrays. If your teacher is making you use raw character arrays...I feel your pain, I remember those days.

Maybe this will help point you in the right direction:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <string>

//Try to avoid doing this in the future, you don't want to get name collisions
using namespace std;

struct employee
{
  int id;
  double salary;
  std::string name; //Strings :D
};


int main()
{
  //TheIdeasMan is right, this should be used instead of just 'int'
  //This type is used  for most things instead of just int
  std::size_t SIZE = 0; 

  while (!SIZE) //!SIZE so they can't enter 0 again. Trust me, your teacher will do this. I promise.
  {
    std::cout << "Enter number of employees: ";
    if (!(std::cin >> SIZE))
    {
      std::cout << "Invalid input" << std::endl;

    }
    //Really, we should use std::numeric_limits<std::streamsize>::max(), but INT_MAX will
    //suffice for now if you don't understand that.  You should look it up, however.
    std::cin.clear();
    std::cin.ignore(INT_MAX, '\n');
  }

  //No need for the initializer loop, you can just do this
  //int *dynamic = new int[SIZE] {0}; //Just one value here is fine, the entire array will initialized to 0

  //But I think you want an array of employees, right?
  //Create an array of employees in the same way
  employee *employees = new employee[SIZE];

  //And you should loop from 0 to SIZE - 1. Remember that we index from 0 in C++
  //and not from 1 like some other languages do
  for (int i = 0; i < SIZE; i++)
  {
    cout << "Enter name for employee number " << i + 1 << ": ";
    std::getline(std::cin, employees[i].name);
  }

  for (int i = 0; i < SIZE; i++)
  {
    std::cout << "employee number " << i + 1 << " name: " << employees[i].name << std::endl;
  }

  //Remember to delete
  delete[] employees;

}



Gives this:
Enter number of employees: i
Invalid input
Enter number of employees: 3
Enter name for employee number 1: Name Number 1
Enter name for employee number 2: Name Number 2
Enter name for employee number 3: Name Number 3
employee number 1 name: Name Number 1
employee number 2 name: Name Number 2
employee number 3 name: Name Number 3
Press any key to continue . . .


Page on numeric limits: http://en.cppreference.com/w/cpp/types/numeric_limits
Page on array initialization: http://www.cplusplus.com/doc/tutorial/arrays/

Sorry if I repeat something you already know. I don't know what your knowledge encompasses, so I'm trying to cover all the bases.
Thanks again Jayhawk! That helps a lot.. I think my issue was that there was a left over whitespace somewhere in my buffer and I was placing cin.ignore in the wrong area haha.. Damn, I'm so rusty, but this was a nice little run down on getting me back into the swing of things again. Now to try and tackle my Data Structures program next O_O

Thanks again to everyone who took their time to post here and help me out! I'll be back with more questions soon, I'm sure.
Last edited on
Topic archived. No new replies allowed.