3

The code currently takes an input of the number of data entries and an input of number separated by a single space. My aim is to get the data entered and convert it into an array however whenever I try using the format

int array[ndata];

The build contains errors due to the variable ndata not being constant. How do I change the input for the size of the array to allow for this?

Code:

#include "pch.h"
#include <iostream>
#include <string>

using namespace std;
int main()
{
    const int MAXDATA = 100;
    bool ok = 1;
    double sum = 0, x, data[MAXDATA];
    double min = 1e32, max = -1e32;
    int ndata = 0;
    int count = 0;

    while (ok)
    {
        cout << "Enter number of data to input then press <Enter>: ";
        cin >> ndata;
        if (ndata > 0 && ndata < MAXDATA) ok = 0;
        cout << "Enter numbers separated by a single space, then press <Enter>: ";
        count = 0;
        while (count < ndata)
        {
            cin >> x;
            data[count] = x;
            sum = sum + x;
            count++;
            cout << "sum is " << sum << endl;
        }
    }
}
voromax
  • 3,369
  • 2
  • 30
  • 53
mathsisu97
  • 41
  • 2

2 Answers2

1

There are 2 ways you can handle this.

Declare Variables Closer To First Use

The first way is to declare your variables closer to where you intend to use them. This is a useful thing to do because it makes it easier to read the code when the declaration and use are close to each other. It would look something like this:

#include <iostream>
#include <string>


using namespace std;
int main(){
const int MAXDATA = 100;
bool ok = 1;
double sum = 0, x;
double min = 1e32, max = -1e32;
int ndata = 0;
int count = 0;

while (ok) {
    cout << "Enter number of data to input then press <Enter>: ";
    cin >> ndata;
    if (ndata > 0 && ndata < MAXDATA) ok = 0;
    cout << "Enter numbers separated by a single space, then press <Enter>: ";
    count = 0;
    double data[ndata];
    while (count < ndata) {
        cin >> x;
        data[count] = x;
        sum = sum + x;
        count++;
        cout << "sum is " << sum << endl;
    }
}

}

Note that with that you'll need to add some additional checks to make sure ndata isn't greater than MAXDATA.

This works because data is declared after ndata is initialized. Note that if you don't check to ensure ndata is less than MAXDATA, you run the risk of overflowing your stack.

Dynamic Allocation

The better way to do this is to allocate the data array on the heap. This allows you to make it as large as you want (up to the limits of your OS and hardware). But it does require extra care to ensure that the data is freed after you're done with it. It would look something like this:

#include <iostream>
#include <string>


using namespace std;
int main(){
    const int MAXDATA = 100;
    bool ok = 1;
    double sum = 0, x;//, data[MAXDATA];
    double min = 1e32, max = -1e32;
    int ndata = 0;
    int count = 0;
    
    while (ok) {
        cout << "Enter number of data to input then press <Enter>: ";
        cin >> ndata;
        if (ndata > 0 && ndata < MAXDATA) ok = 0;
        cout << "Enter numbers separated by a single space, then press <Enter>: ";
        count = 0;
        double *data = new double [ ndata ];
        while (count < ndata) {
            cin >> x;
            data[count] = x;
            sum = sum + x;
            count++;
            cout << "sum is " << sum << endl;
        }
        delete []  data;
    }
    
}
Community
  • 1
  • 1
user1118321
  • 25,567
  • 4
  • 55
  • 86
0

Let's start with a reference for why your build fails: Why aren't variable-length arrays part of the c++ standard? Variable-length arrays are supported by GCC, but not by all compilers.

Vectors

As for what you could do, the safest thing to do would be to switch from arrays to vectors. A std::vector is basically a dynamically-allocated array with some convenience features that mean you don't have to worry about the dynamic allocation. A typical way to declare a vector is the following:

std::vector<double> data;
data.reserve(ndata);

The second line tells the vector to allocate enough space for your data even though the vector at this point still contains no elements. It's not required to reserve space, but it can help performance when ndata is large.

When you have something to add to (the end of) the array, you can use something like:

data.push_back(x);

Retrieving the data can be done with syntax similar to arrays: data[count].

Vectors, part 2

There is another approach you might consider when using vectors. You could declare your variable while specifying its size.

std::vector<double> data(ndata);

This is different than the first approach in that it actually (default-)constructs ndata copies of a double. The first version allocated space but kept the accessible size at zero; this version allocates the space and says that each entry is now valid to access. If you do this, you would not add to the vector, so no pushing. Instead, you could dump the x variable and read directly into the vector entry:

cin >> data[count];

You could also keep x and assign it to data[count], but at that point the push_back approach makes it clearer what is going on.

There are more things that vectors can do; hopefully this is enough to get you started.

Dynamic & Manual

If you cannot use vectors for whatever reason, you might be stuck managing the dynamic memory allocation and de-allocation yourself. The other answer covers this, so I'll just refer you to that one if this is the case.

JaMiT
  • 14,422
  • 4
  • 15
  • 31