initializing the dynamic array of pointer (in a for loop statement) - c++

Please help me to fill the dynamic array (for loop)
i need a way to access other members here in the array such as title, grade, name and age
I'm getting errors when I'm trying to fill it
i think i should do something like
cin >> C[i]. //I don't know what to write here
more background is in the comments
Student::Student(string a, int b, int c) : Person(a, b)
{
/*
my problem is how to open a dynamic array of Courses.
And how to fill them
*/
for (int i = 0; i < numberOfCourses; i++)
{
// dynamic array goes here!
}
}

Solution is to declare new variables and input them by user like
if (cin >> title >> grade >> name >> age)
{
// use values
} else
{
// handle errors
}
and then in the for loop
C[i] = new Course(title, grade, ... );

Related

My program stops with no errror, what did I do wrong?

I have no idea why, but my code just stops at the 2nd for loop in the cin line, if it loops more than 1 time.
Can you help me?
This is my code:
#include <iostream>//Julianne
using namespace std;
int main(){
int a;
cin >> a;
int bezorgen[a];
int afhalen[a];
for (int i = 0; i < a; i++){
cin >> bezorgen[i];
}
for (int j = 0; j < a; j++){
cin >> afhalen[j];
}
return 0;
}
P.S. Sorry for my grammar mistakes.
C++'s declaration
int name[N] is only valid when N is constant. For dynamic sized array (which is in your case dynamic, cause array size comes from user input) you can use:
C++ std::vector<int>
int *name = new int[a]
First one is the list, not an array. So you need to .push_back elements before they can be accesed.
Second one is an array, and accessed just like common array. Be careful with that, because you need to free memory when it's not needed anymore, call delete [] name; at the end of your program for every new type[size] you've done.

Reversing string C++

I tried to create a code that reverse a string, I think my loops logic is correct. But I don't know what is wrong.
#include <iostream>
int main(){
std::cout<<"How many letters does your string have >> ";
int nbre;
std::cin>> nbre;
int a;
a=nbre-1;
char normal[a]={};
char reverse[a]={};
std::cout<<"Enter your string >> ";
std::cin >> normal;
for (int i=0;i<=a;i++){
normal[i]=reverse[a-i];
}
std::cout << "The reversed string is >> " << std::endl;
for (int u=0; u<=a; u++){
std::cout<<reverse[u];
}
return 0;
}
enter image description here
You have to use constant to declare an array this way:
char normal[a]={};
char reverse[a]={};
You can allocate memory like this instead:
char* normal = (char*)calloc(a+1, sizeof(char));
char* reverse = (char*)calloc(a+1, sizeof(char));
and free it once done using it.
The +1 is because you have to account for the ending null char.
I don't think letting the user account for it is a good idea unless your users will only be C-programmers... Better change a = nbre-1; to a=nbre;.
Finally, you should have meant to write your for-loop as:
for (int i = 1; i <= a; i++) {
reverse[i-1] = normal[a - i];
}
I made many changes to your for loop. I will let you do the Homework to understand why.
Personally, I would load the input string into a char array and iterate backwards, starting at the end of the input array and just doing some index math.
Let n = input string length
Iterate from i = n-1 to 0, and load input[i] into reversed[n-i]. Luceion is correct; you're not doing the correct method of actually reversing input string in the first for loop.

C++ struct questions

I've googled relates to struct and I was able to see how they are used; however, I couldn't clearly figure out some of them.
Let's say I have 2 structs
struct Student {
int age;
int height;
};
struct School {
Student information;
};
and let's say I want to handle information School[i].Student[j].age or height based on input file.
int main() {
int school_number = 20;
int student_number = 50;
School school[school_number-1]; // is this the correct way to create it? since [0] is the first school
for (int i=0; i < school_number; i++) {
for (int j=0; j < student_number; j++) {
getline(file, line); // let's say the line has student's age and height.
istringstream c(line);
c >> school[i].information[j].age >> school[i].information[j].height;
}
}
}
I thought this would do the job, but I'm getting no match for 'operator[]' (operand types are 'Student' and 'int') compile error.
What am I missing?
when it's just student,
Student info[student_number-1];
for (int i=0; i < student_number; i++) {
getline(file, line);
istringstream c(line);
c >> information[i].age >> information[i].height;
}
this one works without problem, but I am still not sure what I need to do for 2 structs, where one is calling other one.
One more question,
while I was searching, I see lots of
School *id = new School[school_number-1];
something like this. How does this different from
School school[school_number-1];
this one?
I see a pointer, so I'm pretty sure it does something, but based on how they are used, they look pretty much same.
edit : I've tried little bit, but still not sure how to use vector in this case.
for the above case,
int main() {
vector[Student] student;
int school_number = 20;
int student_number = 50;
School school[school_number-1]; // is this the correct way to create it? since [0] is the first school
for (int i=0; i < school_number; i++) {
for (int j=0; j < student_number; j++) {
getline(file, line); // let's say the line has student's age and height.
istringstream c(line);
c >> school[i].information[j].age >> school[i].information[j].height;
}
}
}
if I call
vector[Student] student;
how can I modify the line
c >> school[i].information[j].age >> school[i].information[j].height;
with the variable student I just created?
If you wanted to declare an array, that must have a const size. What you probably wanted is std::vector<Student>
struct School {
Student information;
};
In this code struct School would contain only one Student object, so school[i].information[j] fails. (It attempts to call operator[] on the Student object school[i].information, which is not defined.)
School school[school_number];
(a C-style array) is not valid C++, because school_number is a variable, and C-style arrays can only have a constant number of items. They are also not recommended in modern C++.
std::array<School, 20> school;
is the recommended way to create an array of 20 School objects.
Because in this code school_number has a fixed value, it could instead be defined as
constexpr int school_number = 20;
and then it can be used with std::array or the C-style array.
Also the array would need to have school_number items, and not school_number-1. school_number-1 is however the index of its last item (because they are counted from 0, when indexing).
For an array with a variable number of items, std::vector can be used:
std::vector<School> school(school_number);
Or alternately, an empty vector is created with
std::vector<School> school;
and then School objects are inserted into it with
school.push_back(sch);
So the program could be written like this:
struct Student {
int age;
int height;
};
struct School {
std::vector<Student> information; // School has array of students
};
int main() {
int school_number = 20;
int student_number = 50;
std::vector<School> schools;
for(int i = 0; i < school_number; i++) {
School school; // first create School object, and then insert it into schools array
for(int j = 0; j < student_number; j++) {
Student student; // same for Student object
getline(file, line);
istringstream c(line);
c >> student.age >> student.height;
school.information.push_back(student);
}
schools.push_back(school);
}
}
School *id = new School[school_number-1];
creates an array of school_number-1, and returns a pointer to it. The pointer needs to be manually freed after use with
delete[] id;
It returns a pointer because the memory gets allocated on the heap.
std::vector<School> does this automatically, and can also increase/decrease the size of the allocated memory when items are inserted/removed from the array.
The way you have declared school it has only one student. You probably want a vector of students instead of one student in your school.
When you declare an array the number that you put inside the bracket is the length of the array. If the length of the array is n you can access elements 0 to n-1 when using the array. When declaring it, you should put n in the brackets though.
Pointers and arrays are very close concepts and in many situations interchangeable. If you have little C experience, sticking with arrays is safer.
School *id = new School[school_number-1];
School school[school_number-1];
the first one is declared on heap memory and the second one is declared on stack. You must delete the first one as soon as you done with it to avoid memory leak.

Creatin a dynamic array including car's year and make but unable to save my first output

I'm working on a specific problem where the output is:
How many cars do you wish to catalog: input
car# 1:
Please enter the make: input_make1
Please enter the year made: input_year1
car# 2:
Please enter the make: input_make2
Please enter the year made: input_year2
Here is your collection:
input_year1 input_make1
input_year2 input_make2
My code is 90% complete, but In my " here is your collection output",I'm not able to save the first one.please help.
#include<iostream>
using namespace std;
struct car
{
char make[60];
int year;
};
int main(void)
{
cout<<"How many cars do you wish to catalog: ";
int j;
cin>>j;
cin.get();
car *ps=new car;
int i;
for(i=1;i<=j;i++)
{
for (i=1;i<=j;i++)
{
cout<<"car# "<<i<<": "<<endl;
cout<<"Please enter the make: ";
cin.get(ps->make,60);
//cout<<"\n";
cout<<"Please enter the year it was made";
cin>>ps->year;
cin.get();
}
cout<<"Here is your collection: \n";
cout<<ps->year<<" "<<ps->make;
}
return 0;
}
I've found a few issues with your code. From what I can tell, you're trying to get a number of cars from the user (j), store them, then print them out. The issue is is that you only have one storage variable (ps). Every time the second loop iterates, it overwrites the ps variable. To fix this you want to create an array of size j. I recommend using a vector, as you don't know the size of the when you compile:
std::vector cars;
//Gets the input from the user
for(int i = 0; i < j; ++i){
car temp;
temp.make = inputStuff;
temp.year = moreInputStuff;
cars.push_back(temp);
}
//Prints the array out
for(int i = 0; i < cars.size(); ++i){
cout << cars[i].make << " " << cars[i].year;
}
The other issue is your double loop. Because they use the same variable to iterator (i), once the inner loop exits, the outer loop will exit as well.
You can't save your entry because you only have one car object and one pointer so you just change the values of that object. You need to create an array of car objects .
You can store your car structures in a vector as you make and fill them.
make sure you #include <vector>
vector<car *> stored_cars;
for ( int i = 0; i < num_cars; ++i ) {
car * ps = new car;
// populate ps with data
stored_cars.push_back(ps);
}
for ( vector<car *>::iterator it = stored_cars.begin(); is != stored_cars.end(); ++it ) {
// you can dereference it to get at the car pointer
(*it)->blah
// make sure you delete the dynamically allocated structs when you are done with them
delete (*it);
}
A better approach would be not to use dynamically allocated memory for the cars.
You'd have a vector of car, vector<car>, and you would just push_back the cars from the stack, and wouldn't have to worry about deleting them all when you are done (vector's destructor will take care of that)
If by "save the first one" you mean the first element of the array then I'll point out arrays in C++ start at index 0. So adjust your loop accordingly: for (i = 0; i < j; ++i )
However you have bigger problems with this such as incorrectly using dynamic allocation and leaking memory, etc. If you want to allocate an array of cars (aka more than one) then do this: car* ps = new car[j];
You then need to explicitly delete them so as not to leak memory with the array delete operator after you're done using them: delete [] ps;
If you want to loop through this dynamically allocated array of cars and update a member of a specific car struct element use the array operator again: cin >> ps[i].year;

C++ changing length of a structure made from an int variable and a pointer to long question

I have created a struct in C++ of the following type:
struct longsir {
int len;
long *sir;
int isinitialised;};
Now, I have to modify the length of a structure, for which I used the following function:
longsir modlen(longsir *s, int newlen){
if (s ->isinitialised ==1 && newlen != s->len) {
if (newlen < s-> len) {
longsir a;
a.len=newlen;
a.isinitialised=1;
a.sir=new long[a.len];
int i;
for (i=0;i<newlen;i++){
a.sir[i]=s->sir[i];};
return a;}
else {
longsir a;
int i; int oldlen=s->len;
a.len=newlen;
a.isinitialised=1;
a.sir=new long[a.len];
for (i=0;i<(s->len);i++){
a.sir[i]=s->sir[i];};
cout <<"Introduceti restul elementelor din sir ";
//Code works till here
for(i=oldlen;i>newlen;i++){
cout <<"Introduceti elementele sirului cu numarul "<<i<<endl;
cin.clear();
cin >> a.sir[i];}
return a;}}}
So, when I choose to use a value bigger than the initial length of the initial array, the code at first creates a new array, after that copies the data from the old array and asks the user to fill in the remaining cells from stdin. Anyway, when running the program, it only asks for introduction of the remaining elements, and after that automatically initialises them to 0. Why is it that the code doesn't work as suggested? I can't find any clue about this situation. Thank you very much for your help.
P.S. You can see the entire original code on Pastebin: the main function and the header file
for(i=oldlen;i>newlen;i++){ maybe i < newlen
for(i=oldlen;i>newlen;i++) there have to be i < newlen I think.