Hey so I want to create n arrays (based off user input) of size x (also off user input). The way I was thinking of doing it was having a for loop perform n iterations and inside the loop ask the user for x. The problem is I'm not sure how to name the array using the variable n, I was thinking something like:
cout << "Enter n: ";
cin >> n
for (i = 0; i < n; i++)
{
cout << "Enter x: ";
cin >> x;
double*array+i;
array+i = new double[x]
}
To sum up my question is: can you create/name an array using a variable in C++?
Unfortunately, you can't do this in C++. Try something like this...
std::cout << "Enter n: ";
std::cin >> n
std::vector<std::vector<double> > arrays(n);
for (std::size_t i = 0; i < n; i++)
{
std::cout << "Enter x: ";
std::cin >> x;
arrays[i].reserve(x);
}
reserve only allocates, but does not construct the objects in the std::vector; if you want to construct them too, use resize.
PS Never use using namespace std; it makes your code harder to read and debug.
Since you are programming in C++, you should use STL containers (especially std::vector) instead of C-style arrays.
If you need to access an array by using the string that has been created in runtime, then you could use std::map< std::string, std::vector<double> >, which is pretty crazy idea though:
typedef std::vector<double> MyVector;
std::map<std::string, MyVector> myVectors;
// create an array:
std::string arrayName;
arrayName = std::string("someArray"); // could be: std::cin >> arrayName;
myVectors[arrayName] = MyVector(10, 1.23); // new vector of size 10
std::cout << myVectors["someArray"][4]; // prints 1.23
I'm not sure what exactly is what you are trying to achieve, but there are most likely more appropriate solutions. Is it really necessary to access these arrays via their names? I'm pretty sure that common std::vector< std::vector<double> > would suffice here.
Here's 3 solutions: the first is closest to your example code, the second is an improvement in order to be able to correctly retrieve the array elements within bounds, and the third is the reason why you are better served with vectors.
Solution 1:
It looks like you want your arrays to have names that are distinguishable by your loop iterator. Like Joe said, you could have an array of an array, so the inner arrays will be named array[0], array[1], ..., array[n - 1]. This will be achieved by using a pointer to pointer to double. Each of the inner pointers will be used to dynamically allocate arrays of double. Don't forget to delete the dynamically allocated memory.
#include <iostream>
int main()
{
unsigned int n;
std::cout << "Enter number of arrays: ";
std::cin >> n;
double** array = new double*[n];
for (int i = 0; i < n; ++i)
{
unsigned int size;
std::cout << "Enter size of array " << i << ": ";
std::cin >> size;
array[i] = new double[size];
for (int j = 0; j < size; ++j)
{
int element;
std::cout << "Enter element " << j << " of array " << i << ": ";
std::cin >> element;
array[i][j] = element;
}
}
for (int i = 0; i < n; ++i)
{
delete [] array[i];
}
delete[] array;
return 0;
}
Solution 2:
However, with the above code, you will have trouble accessing the elements of each inner array. Unless you memorized the size of each inner array you create with this, you might access something out of bounds. Therefore, an update to this code would be to add yet another array, let's call it sizeOfInnerArrays, where each of its element i keeps track of the size of inner array array[i]. Here's the update:
#include <iostream>
int main()
{
unsigned int n;
std::cout << "Enter number of arrays: ";
std::cin >> n;
double** array = new double*[n];
unsigned int* sizeOfInnerArrays = new unsigned int[n];
for (int i = 0; i < n; ++i)
{
std::cout << "Enter size of array " << i << ": ";
std::cin >> sizeOfInnerArrays[i];
array[i] = new double[sizeOfInnerArrays[i]];
for (int j = 0; j < sizeOfInnerArrays[i]; ++j)
{
int element;
std::cout << "Enter element " << j << " of array " << i << ": ";
std::cin >> element;
array[i][j] = element;
}
}
//prints out each array as curly-brace enclosed sets of doubles
for (int i = 0; i < n; ++i)
{
std::cout << "{";
for (int j = 0; j < sizeOfInnerArrays[i] - 1; ++j)
{
std::cout << array[i][j] << ", ";
}
std::cout << array[i][sizeOfInnerArrays[i] - 1] << "}" << std::endl;
}
// free dynamically allocated memory
for (int i = 0; i < n; ++i)
{
delete [] array[i];
}
delete[] array;
delete[] sizeOfInnerArrays;
return 0;
}
Solution 3:
However, that is too complicated, so you are better off using a container, like vector, as Joe suggested, whose data member keeps track of its size.
#include <iostream>
#include <vector>
int main()
{
unsigned int n;
std::cout << "Enter number of vectors: ";
std::cin >> n;
std::vector<std::vector<double> > myVec;
// ^ space between closing angle brackets not needed
// if using C++11 conforming compiler
for (int i = 0; i < n; ++i)
{
unsigned int size;
std::cout << "Enter size of vector " << i << ": ";
std::cin >> size;
std::vector<double> temp;
temp.reserve(size);
for (int j = 0; j < size; ++j)
{
double value;
std::cout << "Enter next value of vector " << i << ": ";
std::cin >> value;
temp.push_back(value);
}
myVec.push_back(temp);
}
for (int i = 0; i < myVec.size(); ++i)
{
std::cout << "{";
for (int j = 0; j < myVec.at(i).size() - 1; ++j)
{
std::cout << myVec.at(i).at(j) << ", ";
}
std::cout << myVec.at(i).back() << "}" << std::endl;
}
return 0;
}
Related
I tried to write this code but it says expression did not evaluate to a constant. I learn that this is because VS does not allow an undeclared array, as "n" is not understood by VS. How can i fix this code with a declared array?
#include<iostream>
using namespace std;
int main()
{
int i, n;
cout << "Enter size of array:";
cin >> n;
int a[n];
cout << "Enter elements of array:" << endl;
for (i = 0; i < n; i++)
cin >> a[(i + n - 1) % n];
cout << "Result after left shift:" << endl;
for (i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}
How can i fix this code with a declared array?
Option 1
Declare the array with sufficiently large size and make sure that n is less than or equal to the size before using the array.
int i, n;
int a[1000];
cout << "Enter size of array (less than or equal to 1000):";
cin >> n;
if ( n > 1000 )
{
// Deal with the problem.
}
else
{
// Use the array.
}
Option 2
Use std::vector.
int i, n;
cout << "Enter size of array:";
cin >> n;
std::vector<int> a(n);
Variable length arrays (VLAs) are not part of the C++ language, although some compilers (like g++) support them as an extension.
You should be using the std::vector container from the Standard Template Library, instead. Once declared and properly initialized, a std::vector can be used much like a plain array:
#include<iostream>
#include <vector>
using std::cout; using std::cin; using std::endl;
int main()
{
int i, n;
cout << "Enter size of array:";
cin >> n;
std::vector<int> a(n);
cout << "Enter elements of array:" << endl;
for (i = 0; i < n; i++)
cin >> a[(i + n - 1) % n];
cout << "Result after left shift:" << endl;
for (i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}
You have to allocate the array on the heap like this:
int* a = new int[n];
But when you do heap allocations, always remember to delete the allocated memory after you are done using it:
delete[] a;
If you don't want to worry about deleting the memory, you can look into std::vector.
I am taking an input from user for the size of an array, and then the elements of it.
In the below code, cin>>A[i] in the first for loop is giving me an error.
From other questions similar to this one, it's a simple operator error, and the script is similar to working three dimensional ones I've seen. Is new creating a 3 dimensional array by default, meaning I'd need to define columns too? If not, where would I be missing the operator?
int** A;
int s;
cin >> s;
A = new int*[s];
for(int i=0;i<s;i++)
{
A[i]=new int[s];
cout<< "Enter value: ";
cin>>A[i];
}
cout<< "Array:\n";
for(int j=0;j<s;j++)
{
cout << A[j] << " ";
}
A[] is an int* pointer, not an int value.
There is no operator>> that can read an int value into an int* pointer. Since you want to read an int value, you have to read into an int variable, so change A[i] in your 1st loop to *A[i] instead:
cin >> *A[i];
You need to do the same with A[j] in the 2nd loop:
cout << *A[j] << " ";
This is because there is no operator<< to write an int value from an int* pointer, but there is an operator<< that can write the value of a memory address held by a void* pointer, and int* is implicitly convertible to void*.
Don't forget to delete[] your arrays when you are done with them:
int s;
cin >> s;
int** A = new int*[s];
for(int i = 0; i < s; ++i)
A[i] = new int[s];
for(int i = 0; i < s; ++i)
{
cout << "Enter value: ";
cin >> *A[i];
}
cout << "Array:\n";
for(int j = 0; j < s; ++j)
cout << *A[j] << " ";
for(int j = 0; j < s; ++j)
delete[] A[j];
delete[] A;
That being said, you are wasting memory for the second dimension when s > 1, since you are filling in and using only the 1st column and ignoring additional columns. The code you showed only really needs a 1-dimensional array instead:
int s;
cin >> s;
int* A = new int[s];
for(int i = 0; i < s; ++i)
{
cout << "Enter value: ";
cin >> A[i];
}
cout << "Array:\n";
for(int j = 0; j < s; ++j)
cout << A[j] << " ";
delete[] A;
If you really want a 2-dimensional array, try something more like this instead:
int rows, columns;
cin >> rows;
cin >> columns;
int** A = new int*[rows];
for(int i = 0; i < rows; ++i)
A[i] = new int[columns];
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < columns; ++j)
{
cout << "Enter value for (" << i << "," << j << "): ";
cin >> A[i][j];
}
}
cout << "Array:\n";
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < columns; ++j)
cout << A[i][j] << " ";
cout << endl;
}
for(int i = 0; i < rows; ++i)
delete A[i];
delete[] A;
That being said, you really should be using std::vector instead of new[] directly.
What array do you want to create? Two-dimensional SxS, or just S-sized?
Because you are creating an array of arrays, while trying to access it as a single-dimensional.
Changing int** A to int* A, A = new int*[s] to A = new int[s], and getting rid of A[i]=new int[s] in the first loop makes the code correct.
I am trying to fill up the multi-dimensional array using dynamic memory allocation and running into problem of how to determine the size of each array.
The sizes are also dynamically generated in the for loop, not sure how i can transport this knowledge into looping construct to tell the compiler when to stop.
Please dont answer the problem directly, just a direction needed so i can figure out on how to solve the problem of determining this,
for (int v = 0; v < sizeof(a[y]); v++)
int** a = new int*[n];
for (int i = 0; i < n; i++) {
int colcount;
cout << "Enter Size of Array for " << i << " : ";
cin >> colcount;
a[i] = new int[colcount];
}
// How to fill the matrix now
for (int y = 0; y < n; y++) {
for (int v = 0; v < sizeof(a[y]); v++) {
cout << "Enter Array Content [" << y << "][" << v << "] :";
cin >> a[y][v];
}
}
Update:
Got it working by bringing the for loop inside.
int** a = new int*[n];
for (int i = 0; i < n; i++) {
int colcount;
cout << "Enter Size of Array for " << i << " : ";
cin >> colcount;
a[i] = new int[colcount];
for (int v = 0; v < colcount; v++) {
cout << "Enter Array Content [" << i << "][" << v << "] :";
cin >> a[i][v];
}
}
Last Update:
To better track contents and privileges of template class, i ended up using vectors and with the help of community, here is how i came up.
int n;
cout << "Enter Num of Vectors: ";
cin >> n;
vector<vector <int> > mult_arr(n);
for (int i = 0; i < n; i++) {
int k;
cout << "Enter size for vec " << i << ":";
cin >> k;
mult_arr[i].resize(k);
for (int x = 0; x < k; x++) {
cout << "Enter Array Contents [" << i << "][" << x << "] :";
cin >> mult_arr[i][x];
}
}
You cannot know or find the size of a dynamic allocated array without actually holding the size in a variable. You can not use the classic sizeof(arr)/sizeof(type) to find the size because the sizeof() a pointer is just its type size and not the total array size. Use std::vector or keep tracking the sizes of each dynamic array.
Instead of using pointers to pointers to int, consider using a single allocation. It is easier and faster!
int * matrix = new int[width * height];
matrix[y * width + x] = 0;
delete [] matrix;
I took the liberty to rewrite your program to a more domatic C++ program (including a main function, so you can test it). Technically, this does solve the same problem, but instead of using new and delete, it uses std::vector, which should always be the first thing you should reach for.
Unless you have a very very good reason not to use vector, I advice you forget about new/delete. Know that it's there and get on with your life.
I realize this doesn't actually answer your question. I think it's too long for a comment so I'm providing it as answer instead.
#include <iostream>
#include <vector>
#include <string>
int get_an_integer(std::string message)
{
std::cout << message;
int n;
std::cin >> n;
return n;
}
int main()
{
std::vector<std::vector<int>> matrix;
matrix.resize(get_an_integer("Number of vectors:"));
for (auto& vector : matrix)
{
vector.resize(get_an_integer("Vector size:"));
for (auto& element : vector)
element = get_an_integer("Element value:");
}
for (auto v : matrix)
{
for (auto e : v)
std::cout << e << " ";
std::cout << '\n';
}
}
Notice how I don't have to keep track of anything and I don't really care about the explicit size of anything. Even the values of the elements aren't interesting.
I hope this helps you. If you have any questions, please ask.
You can memset to initialize an array. like
int *arr = new int[5];
fill(c, c + 5, 3); //fill(array, array+size, intialvalue)
cout<<c[4];
I hope this will help you.
*Edit: Still, when input 3 columns for the 1st row and 2 columns for the 2th, in the output 1st row becomes 2-elemented as the first.
Problem with outputting dynamically allocated number of equipes with separately dynamically allocated number of columns (for number of catches for the each equip)... Namely, if I try to allocate 2 equipes and then for the first equip two "catches" of fish (two columns) and for second equip three catches of fish, everything is o.k.... but if I try input of smaller number of columns ("catches") for the second row (equip) then in the output the "excess" of the first row is "cutted off", so for example if there where a 3 columns input for the 1st row and 2 columns input for the second row, in the output there will be just two columns (indices of numbers) for the every of the two rows.
#include<iostream>
int main()
{
using namespace std;
int *sum;
int *a = new int;
int *b = new int;
cout << "Total number of equips: ";
cin >> *a;
// Allocate a two-dimensional 3x2 array of ints
int** ippArray = new int*[*a];
for (int i = 0; i < *a+1; ++i) {
ippArray[i] = new int[*b];
}
// fill the array
for (int i = 1; i < *a+1; ++i) {
cout << "Total number of catches for " << i << "th equip : ";
cin >> *b;
cout << "Equip number: " << i << endl;
for (int j = 1; j < *b+1; ++j) {
cout << "Catch number: " << j << endl;
cin >> ippArray[i][j];
ippArray[i][j];
}
}
// Output the array
for (int i = 1; i < *a+1; ++i) {
for (int j = 1; j < *b+1; ++j) {
cout << ippArray[i][j] << " ";
*sum = *sum + ippArray[i][j];
}
cout << endl;
}
cout << endl;
cout << "All catches of the all equipes: " << *sum-3;
// Deallocate
for (int i = 1; i < *a+1; ++i) {
delete [] ippArray[i];
}
delete [] ippArray;
// Keep the window open
cin.get();
return 0;
}
First, don't make your integers into pointers (int *a = new int;) unless they really need to be. It makes the code much harder to read, and if anyone has to maintain your code they'll call you an a-hole.
Second, int** ippArray = new int*[*a]; combined with multiple spots where you do this... for (int i = 1; i < *a+1; ++i) are bad. ippArray has valid references from 0 to *a, therefore it should be for (int i = 0; i < *a; ++i)
Edit: Try something like this http://ideone.com/4egQl3
Edit2: Also the standard advice...
{
std::vector<string> advice;
advice.push_back( "These will make your life easier" );
}
// No de-allocation needed!
Parts of your program that have undefined behaviour
Use of *b before you assign to it
Access out-of-bounds elements of all your arrays
Never initialise sum
Use of *sum before you assign to it
cleaned up, your code becomes
int main()
{
using namespace std;
int sum, a, b;
cout << "Total number of equips: ";
cin >> a;
typedef vector<vector<int> > vvint;
typedef vector<int> vint;
// Allocate a two-dimensional structure of ints
vvint ippArray(a);
// fill the array
for (vvint::size_t i = 0; i < a; ++i) {
cout << "Total number of catches for " << i+1 << "th equip : ";
cin >> b;
cout << "Equip number: " << i+1 << endl;
ippArray[i] = vint(b);
for (int j = 0; j < b; ++j) {
cout << "Catch number: " << j+1 << endl;
cin >> ippArray[i][j];
}
}
// Output the array
for (const vint & inner : ippArray) {
for (int num : inner) {
cout << num << " ";
sum += num;
}
cout << endl;
}
cout << endl;
cout << "All catches of the all equipes: " << sum;
cin.get();
return 0;
}
I trying to send array to function, but my program gets stuck
int main()
{
int n, i;
bool random;
cout << "number of elements in array:"; cin >> n;
cout << "use random values?"; cin >> random;
int* arr = new int[n]; //create int array with n size
init_array(random, n, arr); //fill array using function
for (i = 0; i <= n; i++) //display array
cout << " " << arr[i];
return 0;
}
This function should fill array with random number or input from keyboard
void init_array(bool random, int n, int* arr)
{
int i;
if (random)
{
srand(time(0)); //initialize random;
for (i = 0; i < n; i++)
arr[i] = rand() % 100;
}
else
for (i = 0; i<n; i++)
cout << "arr[" << i << "]: "; cin >> arr[i];
}
Is there any way send dynamic array to function?
When you do not use brackets after your for-loop, only the first statement is used as a loop:
else
for (i = 0; i<n; i++)
cout << "arr[" << i << "]: "; cin >> arr[i];
This loop will attempt to print "arr[#]" n times, and then ask for an input (which will attempt to be placed in the item 1 after the last element in your array (UB).
What you want is this:
else
{
for (i = 0; i<n; i++)
{
cout << "arr[" << i << "]: ";
cin >> arr[i];
}
}
You also have a problem with your output:
for (i = 0; i < n; i++) // <= would attempt to print 1 more item than exists in the array
And just for completeness, most of these issues go away when you use a container that does all of this for you:
int main()
{
int n = 0;
bool useRandom = false;
std::cout << "number of elements in array:";
std::cin >> n;
std::cout << "use random values?";
std::cin >> useRandom;
std::vector<int> arr(n);
init_array(useRandom, arr);
std::copy(arr.begin(), arr.end(), std::ostream_iterator<int>(std::cout, " "));
return 0;
}
void init_array(bool useRandom, std::vector<int>& vec)
{
::srand(time(0)); //initialize random;
int n = 0;
std::transform(vec.begin(), vec.end(), vec.begin(), [&](int i)
{
if (useRandom)
{
i = rand() % 100;
}
else
{
std::cout << "arr[" << n++ << "]: ";
std::cin >> i;
}
return i;
});
}
Your code is asking for a number at the end because of last cin>>n
fix else part in init_array as:
else
for (i = 0; i<n; i++)
{ //Notice braces
cout << "arr[" << i << "]: ";
cin >> arr[i];
}
Also fix:
for (i = 0; i < n; i++) //display array from index 0 to n-1
cout << " " << arr[i];