Multidimensional variable length array in C++ [duplicate] - c++

This question already has answers here:
invalid conversion from 'int' to 'int*' [-fpermissive] on passing array
(3 answers)
Closed 4 years ago.
void drawTable(int arg[], int length);
int main()
{
int length=0;
int counter=0;
int *pointer2ArrSize = new int[length];
cout << "Enter length of array: " << endl;
cin >> length;
do{
for(int j=0; j<length; j++){
cout << "Enter array elements: \n";
cin >> pointer2ArrSize[j];
cout << "You entered: " << pointer2ArrSize[j] << " in position: "
<< j+1
<< endl;
counter++;
}
cout << drawTable(pointer2ArrSize[j],length) << endl;
}while(!counter == length);
return 0;
}
void drawTable(int arg[], int length){
for(int i=0; i<length; i++){
cout << arg[i] << " ";
cout << '/n';
}
}
error: invalid conversion from 'int' to 'int*' [-fpermissive]
My goal is to display a 2D variable length array. I want the user to define the length of the array and the elements in it. However, am not too familiar with vectors yet. how could I approach this?

cout << drawTable(pointer2ArrSize[j],length) << endl;
is wrong since the argument type for drawTable is int* and you are passing pointer2ArrSize[j] to it, which is of type int.
You need to use
cout << drawTable(pointer2ArrSize, length) << endl;
More importantly, use of
int *pointer2ArrSize = new int[length];
cout << "Enter length of array: " << endl;
cin >> length;
is wrong.
The array will not be resized to length after you accept its value from the user. Consequently, pointer2ArrSize will continue to be an array of size 0. Since pointer2ArrSize continues to be an array of size 0, any attempt to access its elements will result in undefined behavior.
Move the line that allocates memory after you have accepted the input value for length.
cout << "Enter length of array: " << endl;
cin >> length;
int *pointer2ArrSize = new int[length];
It will be better still to use std::vector. Then, you don't have to worry about memory allocation and deallocation.
cout << "Enter length of array: " << endl;
cin >> length;
std::vector<int> pointer2ArrSize(length);
Of course, you should change drawTable to accept a std::vector<int>.
void drawTable(std::vector<int> const& arg);
There won't be the need for length as a second argument to drawTable since you can get the size of the array from the std::vector.

Related

C++ POINTERS (student * [n] gives the error that array type is not assignable)

#include <iostream>
#include "student.h"
using namespace std;
int main()
{
// inputting the number of students
int n;
cout << "How many students would you like to process?" << endl;
cin >> n;
student* s[n];
string tmp;
double t;
// entering each student details
for (int i = 0; i < n; i++)
{
// dynamically allocating object
s[i] = new student();
cout << "Enter first name for student " << (i + 1) << endl;
cin >> tmp;
s[i]->setFirstName(tmp);
cout << "Enter middle name for student " << (i + 1) << endl;
cin >> tmp;
s[i]->setMiddleName(tmp);
cout << "Enter last name for student " << (i + 1) << endl;
cin >> tmp;
s[i]->setLastName(tmp);
cout << "Enter GPA for student " << (i + 1) << endl;
cin >> t;
s[i]->setGPA(t);
}
double avgGPA = 0;
// printing the student details
cout << "Students:" << endl;
cout << "---------" << endl
<< endl;
for (int i = 0; i < n; i++)
{
cout << s[i]->getFirstName() << " " << s[i]->getMiddleName() << " " << s[i]->getLastName() << " " << s[i]->getGPA() << endl;
avgGPA += s[i]->getGPA();
}
avgGPA /= n;
// printing the average GPA
cout << endl
<< "Average GPA: " << avgGPA;
// freeing the memory allocated to objects
for (int i = 0; i < n; i++)
delete s[i];
return 0;
}
Under the main function student * s [n]; says the array type is not assignable to the line.It also gives an error that the expression must contain a literal. I thought I was doing everything right, but there was an error. What is the solution to this error can anyone help?
student* s[n]; is a Variable-Length Array (VLA), which is not in the standard C++.
You should use std::vector like std::vector<student*> s(n);.
Also add #include <vector> at the beginning of your code to use that.

Making a pointer to an array of structures

Having difficulty solving the below challenge.
My attempt is the code below the struct. I'm not quite clear as to how I would save the individual entries to the array as when I attempt to use a bracket to index each entry into the loop i'm met with an error.
Is there something I'm missing or overthinking?
Use the Time structure to define and dynamically allocate memory for an array of 10 times. After that return the allocated memory back to the operating system
struct Time {
int hrs;
int min;
int sec;
};
Time *t2 = new Time[10];
for(int i = 0; i < 10; i++){
cout << "Enter time in format HHMMSS "<< i + 1 << ": ";
cin >> t2->hrs>>t2->min>>t2->sec;
}
cout << setw(8) << "INDEX" << setw(10) << "Time" << endl;
for(int i = 0; i < 10; i++){
cout << setw(8) << i << setw(10) << t2->hrs <<":"<< t2->min<<":"<<t2->sec<< endl;
}
delete[] t2;

Dynamic array crashed for more than 8 elements

#include<iostream>
using namespace std;
void arrayin(int x[], int n);
void arrayout(int x[], int n);
main()
{
int n, x[n];
cout << "Please enter the number of elements in the array: " << endl;
cin >> n;
cout << "Please enter the elements: " << endl;
arrayin(x,n);
cout << "Array is of " << n << " elements."<< endl;
cout << "Elements are as follow :" << endl;
arrayout(x,n);
}
void arrayin(int x[],int n)
{
for (int i = 0; i < n; i ++)
{
cin >> x[i];
}
}
void arrayout(int x[], int n)
{
for (int i = 0; i < n; i++)
{
cout << x[i] << "\t";
}
}
I'm new to programming.
It crashes for more than 8 elements, if n > 8 crashes.. but for n<8 works fine..
Dont know why!
Here is the problem:
int n, x[n]; // It is undefined behaviour
cout << "Please enter the number of elements in the array: " << endl;
cin >> n;
The correct way is (on your compiler with the variable-size-array extension):
int n;
cout << "Please enter the number of elements in the array: " << endl;
cin >> n;
int x[n];
The correct way using C++ is to use std::vector instead:
int n;
cout << "Please enter the number of elements in the array: " << endl;
cin >> n;
std::vector<int> x(n);
and you have to make some other changes to adapt std::vector.
The problem is here:
int n, x[n]; // <-- n is not yet initialized
cout << "Please enter the number of elements in the array: " << endl;
cin >> n;
cout << "Please enter the elements: " << endl;
arrayin(x,n);
You need this:
int n;
cout << "Please enter the number of elements in the array: " << endl;
cin >> n;
int x[n]; // << now n has been initialized
cout << "Please enter the elements: " << endl;
arrayin(x,n);
BTW: VLA (or dynamic arrays as you call them) are non standard in C++, but gcc (and possibily clang) has them as extension.
int n, x[n]; is the problem
You are declaring n that will have an indeterminate value. With this value you are declaring an array that will have an indeterminate size.
You are using C++, so use new keyword to create your array, after user input:
cout << "Please enter the number of elements in the array: " << endl;
cin >> n;
int *x = new int[n];
// your stuff
delete x;
Declare your array after taking input for n.
#include<iostream>
using namespace std;
void arrayin(int x[], int n);
void arrayout(int x[], int n);
main()
{
int n;
cout << "Please enter the number of elements in the array: " << endl;
cin >> n;
int x[n];
cout << "Please enter the elements: " << endl;
arrayin(x,n);
cout << "Array is of " << n << " elements."<< endl;
cout << "Elements are as follow :" << endl;
arrayout(x,n);
}
void arrayin(int x[],int n)
{
for (int i = 0; i < n; i ++)
{
cin >> x[i];
}
}
void arrayout(int x[], int n)
{
for (int i = 0; i < n; i++)
{
cout << x[i] << "\t";
}
}
This code works. The problem is when you declare array with no value for n the array will be initialized with whatever is on stack from past. Variable length arrays require the value. So declare the array later.
Someone downvoted without any reason.
Edit: Variable length arrays are not part of ISO C++. To write standard compliant C++ code you should use -pedantic flag with g++ or clang.
You have two simple choice. Either use std::array for fixed length arrays or std::vector for dynamic arrays.

Operating on functions and arrays

The purpose of this program is for the user to declare the size of their array, then have various functions operate on it. My problem is I realize nothing valid is declared in FunctionTwo. How can I get information from my main function to FunctionTwo and so on for my other functions as well?
int main()
{
srand(time(NULL));
int arraySize = 0;
cout << "How large would you like your array to be?" << endl;
cin >> arraySize;
int theArray [arraySize];
int selection = 0;
cout << "What would you like to do with your array? " << endl << endl;
cout << "1. Pass in an integer location and return the value. " << endl;
cout << "2. Initialize an array of all 0's. " << endl;
cout << "3. Initialize an array of random numbers between 1 and your specification. " << endl;
cout << "4. Populate an array one at a time. " << endl;
cout << "5. Select a position in the array and set that value to your specification. " << endl;
cout << "6. Print the entire array. " << endl;
cout << "7. Find the average of each value in the array. " << endl;
cout << "8. Find the largest element of the array. " << endl;
cout << "9. Find the smallest element of the array. " << endl;
cout << "12. Print all numbers in the array larger than your input. " << endl;
cout << "13. Tell if the array is empty. " << endl;
cout << "15. Return the difference between the largest and smallest value in the array. " << endl;
cin >> selection;
}
int FunctionTwo()
{
int theArray [arraySize] = {0};
return theArray;
}
int theArray [arraySize]; is not valid C++ if arraySize is only known at run-time.
The correct solution for your problem in C++:
std::vector<int> theArray(arraySize);
In C++ the size of an array shall be a constant expression known at compile time. This code
int arraySize = 0;
cout << "How large would you like your array to be?" << endl;
cin >> arraySize;
int theArray [arraySize];
is not C++ compliant because variable arraySize is not a constant expression.
So either you will set a fixed size of the array yourself without asking the user to specify the size as for example
const int arraySize = 20;
int theArray [arraySize];
or you must to allocate dynamically the array as for example
int arraySize = 0;
cout << "How large would you like your array to be?" << endl;
cin >> arraySize;
int *theArray = new int[arraySize];
In this case do not forget to delete the array before exiting the program:
delete []theArray;
You could use standard container std::vector<int> but I am sure that your assignment requires to use an array.
As for the function call of FunctionTwo then the function has to have two parameters: pointer to the first element of the array and the number of elements in the array. There is no sense to declare its return type as int, It would be better to declare it as void Here an example
void FunctionTwo( int theArray[], int arraySize )
{
for ( int i = 0; i < arraySize; i++ ) theArray[i] = 0;
}
Or you may use standard algorithm std::fill. For example
#include <algorithm>
//...
void FunctionTwo( int theArray[], int arraySize )
{
std::fill( theArray, theArray + arraySize, 0 );
}
Here is an example of so-called FunctionThree that has to initialize the array with random numbers in the range [1, n]
void FunctionThree( int theArray[], int arraySize, int n )
{
for ( int i = 0; i < arraySize; i++ ) theArray[i] = std::rand() % n + 1;
}
Or the same but using standard algorithm std:::generate
#include <algorithm>
//...
void FunctionThree( int theArray[], int arraySize, int n )
{
std::generate( theArray, theArray + arraySize, [&] { return ( std::rand() % n + 1 ); } );
}
Take into account that functions shall be declared before their usage.
As for the menu that it should be enclosed in a loop. For example
do
{
cout << "What would you like to do with your array? " << endl << endl;
cout << "1. Pass in an integer location and return the value. " << endl;
cout << "2. Initialize an array of all 0's. " << endl;
cout << "3. Initialize an array of random numbers between 1 and your specification. " << endl;
cout << "4. Populate an array one at a time. " << endl;
cout << "5. Select a position in the array and set that value to your specification. " << endl;
cout << "6. Print the entire array. " << endl;
cout << "7. Find the average of each value in the array. " << endl;
cout << "8. Find the largest element of the array. " << endl;
cout << "9. Find the smallest element of the array. " << endl;
cout << "12. Print all numbers in the array larger than your input. " << endl;
cout << "13. Tell if the array is empty. " << endl;
cout << "15. Return the difference between the largest and smallest value in the array. " << endl;
cout << "\n0. Exit from the program" << endl;
cin >> selection;
//...some other code
} while ( selection != 0 );
How can I get information from my main function to FunctionTwo and so on for my other functions as well?
You can provide function arguments. For example:
int FunctionTwo(std::vector<int>& the_vector)
Then in main():
switch (selection)
{
case 2: FunctionTwo(the_vector); break;
...other cases...
}
int FunctionTwo(int[] theArray) {}
This would allow you to use theArray inside the function. Hopefully this is what you meant. I was somewhat unclear on exactly what you wanted to do.
Now you can call the function as so:
FunctionTwo(anArray);

ISO C++ forbids comparison between pointer and integer?

Here is the code:
void option5 (StudentRecord student[], int n)
{
double gpaThreshold;
char enteredMajor;
int i;
cout << "Enter a GPA threshold: ";
cin >> gpaThreshold;
cin.ignore(80, '\n');
cout << "Enter a Major: ";
cin >> enteredMajor;
cin.ignore(80, '\n');
enteredMajor = toupper(enteredMajor);
for (i = 0; i < n; i++)
{
if (student[i].gpa >= gpaThreshold && student[i].major == enteredMajor)
{
if (i % 10 == 0)
{
cin.ignore();
}
cout << setw(3) << right << i+1 << ". "
<< setw(20) << left << student[i].lastName
<< setw(20) << left << student[i].firstName
<< setw(8) << left << student[i].major
<< fixed << setprecision(2) << setw(8) << left << student[i].earnedHours
<< fixed << setprecision(2) << setw(6) << left << student[i].gpa << endl;
}
}
}
StudentRecord is a struct, and the only integer on that line is 'i', whereas the pointer (I would have to assume) is .major.
I'm wanting to compare an entered major, with the "Major" values in the array.
E.G. I type in Chem
-turns to CHEM
-fetches all students under that major (and threshold of GPA)
-displays the above statement (all students of 'X' major)
Any suggestions? Help? Comments? Positive/Negative Feedback?
EDIT: Here is the struct:
struct StudentRecord
{
char lastName [16]; // field definitions of the structure
char firstName[16];
char hometown [16];
char major[5];
int studentNumber;
double balance;
int earnedHours;
double gpa;
};
Consider this fragment:
student[i].major == enteredMajor
student[i].major is a char[5], which devolves into a char* in this context. This is a pointer type.
enteredMajor is a char. This is an integral type.
You cannot compare these types.
Perhaps you meant to decalre enteredMajor thus:
char enteredMajor[5];
and compare them like this:
strcmp(student[i].major, enteredMajor) == 0
student[i].major is a char array; when used in an expression it decays into a pointer to char. The code compares it for equality with enteredMajor which has type char. Thus the complaint: can't compare a pointer and an integer (because char gets promoted to int).