Again, welcome to another lecture on structs.
We're going to continue on talking about this subject, and we'll go into a little more detail about
the different things we can do as strikes.
So first thing I want to introduce is another way to initialize a struct.
So you notice here we have a struct called employee.
It has one two three four data members down here and main.
When we make in an instance of an employee and we call that variable e one, you notice that we are
able to initialize it kind of like in an array or vector initialization list form.
So this is an initialization list like you can do with vectors and race and such.
You notice that we're putting some values in here and you may be wondering, well, how do you know
which one goes to which variable in our struct?
It's actually just all in order.
So since we have ID first, then name then group than ours, that's how it is from left to right here.
So I.D. will be initialized to this number right here.
Name will be initialized to Fred right here.
Group will be initialized to see and ours will be initialized to this float.
Forty three point five.
So pretty cool, I just wanted to point out another way that you could initialize struts and of course,
right here on this next line, we're just printing it out by using remember the dot operator here.
So we're doing employ one I.D. to access the ID, which is this right?
So this will print out.
Then we do employ one name which will print this out a comma separated, separating all this by commas,
uncrewed, which will be this right here.
And then he went on, Ours right here.
So the main thing is just to recognize that there is this other way to initialize your structs, the
members of your structure, the data members.
So the next thing I want to talk about is the fact that you can have arrays and vectors of struts.
And what I mean by that with the of is that the data type of the array or the vector can be a struct
type that you've defined, right, the abstract data type.
So this is employee again, right?
So let's go ahead and take a look.
So right here we have our employees strut.
We have the same thing ID, name group hours, right?
Just like before you notice a main, what we do here is we create three employees with these initialization
list styles, right?
We're using that same thing where we have the brackets and separated by commas.
It's a list and we're doing them in the order of the appearance.
Top to bottom of the data members, right?
So I.D. is the leftmost.
The name comes here group is here, right?
So same thing that we were just talking about in the previous slide.
So below that, you notice we initialize this array of size three and the type of the array is employee.
So let's take a look at that and let's see what's going on here.
So here is that enhanced a bit in size.
So we make an array of size three call it array for the variable air and type employee.
So just like you put tape and we now have our own type right and abstract data type called employee,
and that is the type of the array.
Same thing for the vector.
Normally here you could see end or string in between these, right?
But now we're seeing our data type that we created employee, right?
So same thing as putting an end or string or float in here.
We're putting our own abstract data type inside of here.
We call this effect right now.
What I'm doing is I'm just setting each one of the positions of the array to be each one of the employees.
So I say, Ah, which is our employee or a zero equals e one position, one equals E two position two
equals E three, right?
So we're taking these three employees we created and putting them in the three positions of our array
of size.
Three.
Right.
The vector, I'm using the pushback function and I'm just pushing back employees just like we kind of
added them to the array.
Now I'm using the push back function to add them to the employee vector.
So then we come down to here where I'm actually printing them out, so I'm only printing out the array
ones here, but you see when I commented, my comments over here show what it would be if it was the
vector pretty much be the same thing, right?
So all we're doing is indexing it just like normal.
And then what we're doing, though, is putting a dot right here and then printing out each one of the
attributes.
One of the member sorry data members here, right?
So ID name group hours.
Remember, we access those with a dot.
You might be wondering, Well, this is weird.
You have the name of the array in your indexing.
And then like right after the subscript operator brackets, here you put a dot.
Isn't that a syntax problem and error?
Well, no, it's not.
Because let's think about what this is that I'm circling right here.
What is e RR subscript i or index AI, right?
Let's think about the first time that this loop runs.
It's zero, right?
So r i, what would that alone give us just this alone?
Well, we noticed that e r zero is e one, which is an employee, right?
We describe that employee here.
So you can actually replace this whole thing that I'm circling right here.
The E.R. subscript AI, when it's zero, you can replace that with A1 because that's what it's getting
out of it, right?
This was what's stored there.
So it returns that back to us.
Now, imagine doing a one I.D. that's essentially what's happening.
We're indexing the array to get E1 out of positions zero right.
When we do, the first loop is zero.
So we're getting E one out right here.
And then once we have one, we do dot I.D..
So that is what C++ is seen here.
You know, it's like, OK, this gets resolved it.
Let's get whatever's out of that array.
You know, all the bytes and that happens to be this object here.
This sorry, the struct, which is E1.
And then we do e wonder ID.
And then I'm going to pronounce the ID.
And then the vector would be the same thing.
It's just event set of script I.D. instead of e a R because we just called it different, you know,
but vectors are subscript at the same.
The point is that when we use these subscript operator, which is these brackets here and we're indexing
it, it's giving us this struct, employee type, right?
And it's specifically for the first loop iteration is giving us E1.
So each time we call ID Dot Name Dot Group to ours, we're really doing E1 to ID, E1 got name, E1
Dot Group and E1 hours.
All right.
So that is what's going on.
So now that we've kind of cleared that up and explained how to make vectors and arrays of strikes,
let's go ahead and have a quick challenge.
So I want you to pause the video after I explain this.
And what you're going to do is read in data from a file into a vector of structures.
The file is going to look like this.
It's going to be here's like one line and here's another line and so on and so forth.
It's going to be name, which is a string space age, which should be an integer space weight, which
will be a float and there'll be multiple lines of that, right?
So I want you to actually go ahead and create your own file that is in this format, right?
It's like a string for a name.
And then, you know, the age is a number and the way is some decimal number, decimal point number,
and you're going to read that this stuff into a string and end in a float, respectively, right?
So what I want you to do is like each line is going to be represented with a struct, an instance of
a struct, right?
We're talking about a variable think about like E1, right?
So if this was an employee rather than like a person or whatever, you know, this would be this whole
line here would be like E1, right?
This would be to like if we're thinking back to this example, right?
We had we made our struct here where we kind of defined it right.
Then here we make an instance of our struct.
We made a variable called E1, its type employee, right?
And here is an instance of our struct.
So each line in the file represents an instance of the struct.
So I want you to be able to look to the file.
Read all these in to a struct, and then I want you to make a vector of all these drugs and then print
out that vector abstracts.
OK, so that is your challenge.
So you can go ahead and refer to the previous slides if you go back in the video if you need to go ahead
and pause video here.
All right, so let's go ahead and get started with this problem.
So go ahead and go to the GPS code here.
So I have a couple of files here.
The first one is to keep I know I'm going to want to include I stream to print out.
I'm going to include Airstream to read from a file and I'm going to include Vector because I'm going
to have a vector of straps.
Right here is the other file.
It's a text file.
It has each line as described in the problem.
We have a name, right?
Like Bob, he's age 20 and this float here is the weight, and he's two hundred two hundred point five
pounds or kilograms where you want to call that.
So let's go ahead and get going with this.
So I'm going to know I'm going to make a struct for sure, right?
So I'm going to say struct person and I'm going to go ahead and put a semicolon at the end because we
know we need that.
And what are the members going to be?
They're going to be string name, right?
And age and float.
Wait, right.
So there's our struct.
The next thing I want to do is I think I'm going to add command line args, so I'm going to say and
ARG C and Char are really so this will let us kind of specify the input file and the command line.
So we can say person underscore input that here in the console.
Since I'm doing that, the first thing I'm going to check is to see if ARG C is not equal to two.
So that means they have not provided an input file.
We will do our standard.
You know, this is how you use the file.
You're going to run the file name and input input file name here, something like that, right?
And then we'll go ahead and exit if that's the case.
So the next thing that I'm going to do is I'm going to go ahead and declare my input stream.
So I'm going to say I have stream my stream and then I will do my stream open and we'll do our re one,
right?
Because that's going to be the command line argument will be at our be one in the argument vector,
right?
The position one next thing I'm going to do is make my vector.
So what type is the vector going to be?
It's going to be a vector of.
People write so vector type person, a person is our struct name, we we a person right here.
So Vector Person, I'm just going to call this person vector, you know, pretty original there.
And then what else do we need to do?
So we're going to read into some structure.
We're going to want to loop through the file.
What I'm going to do is actually makes I'm going to do this in two ways I'll show you, I'm actually
going to do it in a few ways, probably more than two.
You are going to show you kind of different ways that we can handle this problem.
So what I do is make some variables first, right?
I'm going to say string name, MSA and age, and I'm going to say float.
Wait here, just straight up local variables.
So this is one way that you could do this.
And then what I'm going to do is I'm going to make a loop that loosened the file, and I'm just going
to read into all three of these right here in the while so I can say my stream while we are able to
read into our stream.
A name followed by an age, followed by a week, so let's keep looping through the file as long as we
can read all three of these into these variables with our input stream.
So that is a loop that you can use.
So we're just going to read into all of these variables, these local variables right off the bat.
And then what do we do?
Well, we can make a person each time, write a new person.
So this is us just reading, and we know that the file format is name, age and weight.
So that's why we're doing this.
You know, it's kind of we're taking the easy way out because we know that name is followed by age is
followed by wait in the file.
So we're just reading them assuming it's all going to come in this order like this.
And then I make a new person each time because each line, each name, age and weight line is a new
person, right?
So what I'm going to do is I'm going to now that I have a new instance of a person.
Right, I made an instance of this struct, I can now set the variables right, so I'm going to say
P nickname equals name because I already read in the data into this variable, right?
The first line of the file is Bob, so I basically read Bob into here.
I read Bob's Age and here.
And then I read Bob's waiting to hear, and now I've created a new person, I can now set that person's
attributes or name or variables to what the variables are already holding right here.
The local variables are already holding the values for Bob, right?
So Peter, name equals name Pete.
Our age equals age.
Pete weight equals weight.
Now what?
We filled a person instance p with all of the necessary data.
Now what we can do is push it back to the person vector, a vector of type person called Person B person
x push back P.
We're adding the person to the person vector and this is all we really need to read it in.
All we got to do now is print it out.
So to say four in April, zero, I is less than however many items are in person bag.
So a person like that size and then I plus plus what am I doing here is I'm going to say c out name
and I'm going to say person backed in here.
Think back to the lecture.
We do person vector subscript.
I dot name, right?
And then an inline.
So think back to this right.
This person vector AI is going to resolve to the person instance, right?
So each person, right?
So for persons zero, that's going to be bob, right?
So person vector AI.
Gets us.
You know, all of Bob Wright, the whole structure, the whole up person.
And then we're going to say, OK, so p, this is Bob Bob not name is Bob right?
So this whole thing right here resolves to a person we're substituting into the victor and getting the
specific person out of the right position, right?
So then I say, see our age and I'm going to say the same thing is going to be person that I but person
that guy, age
and line while I'm struggling to type C out and I'm going to say wait or struggle, person.
In fact, I don't wait in line.
And now we've turned out everything to do with the person.
I'm going to add an extra new line here just to separate them a little bit more.
So I have this in their.
So this should be everything, let's go ahead and test it out, I do need to close my file, so I'm
going to go ahead and close it here when I'm done, so I'll say my stream close right here.
And yeah, we should have everything working, so I'm going to go ahead and save this and then I'm going
to go hang a pilot, so I'll say Gee Plus Plus and this will be cigarettes.
Five That CBP dash.
Oh, and we call this five, see?
All right.
So compilers, OK, so what are we expecting from this?
We're expecting it to print.
Things on a new line for each person, so should say name.
Bob, let's see.
Let's just go to here.
It's just a name.
Bob, age 20, weight two hundred point five and then put a little new line like space.
And then it's just a name, Nancy.
Age 65, weight one or two point three, and so on.
So let's go ahead and run this and double check that.
That's what we get.
Well.
But down here.
Oh, yeah, we forgot to put the file name, right, so let's go ahead and say person input.
All right, so let's see what we got here.
I'm going to scroll up so we can verify, and that looks like our file, right?
So we have named Bob Age 20 Weight ten point five space.
We got Nancy's info and then Jeff down here.
So pretty cool, right?
We can put these strokes into vectors and we can now read in from files and put stuff into our own abstract
data types and store those in a list in a vector.
So now we have multiple abstract data type instances, right?
We have three different people stored inside of a container, right?
They're stored in a vector.
So that is something pretty cool.
We're getting kind of better and better at being able to represent interesting ideas and code here.
So I'm going to clear that and we'll go back to here.
So another thing that I want to go over, though, is do we have to make a new person each loop?
Could we just use the same instance of a person except each time we go through a loop?
We change their data.
We change the data of that person and then add it to the vector right in the next time we change the
data of this person and add that to the vector.
Would that work?
So think about it.
Are we referring to the same memory or are we making copies?
So let's go ahead and try something else out.
Let's go ahead and put the person here.
And I'm not going to make a new person each live, I'm just going to use one person.
And what I'm actually going to do is I'm going to read straight from the file into the data members
instead of having these local variables.
OK, so I'm going to actually delete all of this, and what I'm going to do is delete all of this as
well, and we're literally only going to have this, but I'm going to put P Dot name here.
PETA age here and PETA wait here.
So what I'm doing is now I'm reading straight from the file.
Into some reading from the files straight into the struct, right, so I made an instance of a person
write.
And I'm reading straight into the data member now right here, so we got the name goes straight into
the data, remember the age goes straight into the data.
Remember the wait goes straight into the data, remember?
Now we've read into all three of these.
What we do is we pushed that person into the vector.
So that's now stored in that vector.
Said the big question is, is it stored, is it a copy that's stored or?
Is it going to have like, you know, are we going to keep changing that person like let's say, let's
say we change the person each time, is it going to keep changing?
Each one of the people inside the vector, so they all say, Jeff, because Jeff is the last one, we
change it to, right?
Is it going to change the already existing people that are stored in our vector of people?
That is the question.
So let's go ahead and run it and find out.
So I'm going to go ahead and compile this, and then I'm going to go ahead and running again.
So let's see what it says, we see Jeff there at the end.
Let's scroll up.
So no, it actually it actually saves copies.
Right?
And that is because we're not using a pointer to the person.
We're not changing the same memory, right?
Each time it's adding a new copy to the vector, except we're not explicitly making a new person here
with our code like we're not doing this anymore.
Right, so this is a slightly more efficient way to do it, it is still putting copies inside the vector.
Right?
So each person is going to be different in the vector.
But what would it look like if we were referring to the same person with a pointer?
So this is actually going to bring up a kind of new and more complex topic to do with strikes and in
the next lecture, we are going to go over this in more detail.
So what I'm going to do is just kind of introduce it now to kind of show you what it would look like.
And then we're going to get into detail in the next lecture.
So don't worry if I kind of leave you hanging a little bit on this, but let's just say, what if we
had a pointer, right?
How would we make a pointer to a person, right?
What if we dynamically allocate a new person each time?
So not only are we're making it just a pointer, but we're dynamically allocating it each time.
So if I go person star piece and now it's a pointer and I say equals new person, right?
We're doing it just like we've done previously with dynamically allocated memory right here.
Is that dynamically allocated part and we have to make a pointer now since it's on the heap and we need
to point to it.
We need to change our vector now because it's not a vector of type person anymore, it's a vector of
person pointers.
So we're going to say vector of person pointers.
Another interesting thing is this dot, we actually can't use this dot anymore to read into the name,
age and weight.
Since it's a pointer, we have to use a new weird little operator here and it's going to be an arrow,
right?
But it's an arrow with a minus and a greater than.
It's a little bit weird, but you can think of it as pointing to something, right?
It looks like a pointer like that you would think of in your mind.
Like it's it's an arrow, an arrow points, right?
So that is why we're going to use this syntax.
It's a minus sign in a greater than symbol right afterwards, but you can think of it as an arrow because
that's more so what it means, right?
Because it's having to deal with a pointer.
So we need to use this instead of a dot now since we're having a person pointer instead of just a normal
person variable.
So I'm going to do this arrow named Arrow AJPW Arrow.
Wait.
All right, then down here, we actually have to replace these dots as well, because this is going
to resolve not to just a person, but a person pointer, right?
Look at that.
It hovers up here.
It says Vector Person type person pointer.
So we're actually going to need to put arrows here as well.
And this is something that I'm going to get into more in the next lecture.
So don't worry too much.
I'm just kind of giving you a little introduction now to also show you what's going to happen if we're
pointing to the same memory.
What we're storing in the vector now is not a new person each time it's actually a new address.
Not even a new address was stolen, a new pointer in that pointer, they're all pointing to the same
memory location that stores the person, so this is going to yield some different results.
So I'm going to go ahead and save this now.
And let's see what happens, hopefully updated everything correctly to be able to use the pointer if
we encounter some errors, we'll just have to fix them.
So let me go ahead and recompile it.
Looks like it compiled, OK, so let's go ahead and do step five.
And now what do you think the output is going to be?
So try and predict the output.
We got these people in here, right?
Go through the code in your head if it's a pointer.
You know, what's going to happen each time when we start to the victor, it's just pointing to the
same person that we made.
So think about what this victor is going to say in the long run in the end of everything.
So let's go ahead and run it.
Well, that is interesting, isn't it?
So look at this now, everything is Jeff.
So why is everything, Jeff?
Well, everything is Jeff, because Jeff is the last thing that we updated it to when I say updated
it.
Yes.
There's only one person.
And we're just literally storing a bunch of pointers pointing to the same person, right?
So we point to some chunk of memory that has this structure, the person struct, we make a new dynamically
allocated person.
What we do is we read in from the file.
Bob, twenty two hundred point five.
Right, so we read all those in and we set the data of that person, we set the member variables of
that person.
It's all bad right now.
What we do is we push back, not the person.
But the person pointer to the vector, right, we're storing person pointers now, so we store a little
memory address of where Bob exists.
What do we do the next move?
Well, we go in here, we're referring to the same piece of memory, we're pointing at Bob and now what
we're doing is we're saying.
Well, Bob's name is Nancy, actually, and he's this old and, you know, now it's like, she's this
old and she has this wig, so it's not even Bob anymore.
The same memory has been overwritten with Nancy's data.
So it's been overwritten with Nancy's data.
Then what we do is we come back the next time and we overwrite the person with Jeff, and we're doing
that for each item in the vector because the vector is just storing the pointers, right?
So why don't we loop through the vector?
We're actually just going through a bunch of things that point to the same memory.
Right.
So if I was to change this to Nancy, all of these are just going to say Nancy instead of all of them
saying Jeff.
So they all say Jeff, right now, let's go ahead and run, and again, I'm not going to recompile it
or anything.
I'm just going to run again.
Look at that.
They'll say Nancy now.
So it doesn't matter what comes before here, it's only the last thing that matters.
They're all going to just be updated to the last thing in our list, right?
The last thing in the file.