#include <iostream>
#include <ctime>
#include <cstdlib>
#include <limits>
#include <iomanip>

using namespace std;

// to show pointer used in function as array
void print_per_line(const double a[], long max, long wide = 10);

// to show pointer used in function as pointer
long read_to_fail(double * a, long max);

int main(void)
{
    double * p;
    short max, count;

    srand(static_cast<unsigned>(time(nullptr)));   // for later...

    // make things look nice...
    cout.precision(4);
    cout.setf(ios_base::fixed | ios_base::showpoint);

    // a single double from the heap:
    p = new double;
    if (p != nullptr)
    {
        *p = 18.01;
        cout << "\n*p is " << *p << ".\n";
    }
    else
    {
        cout << "\nCouldn't get space for a single double!\a\n";
    }
    delete p;
    p = nullptr;  // clean up nice...

    // a single double with initialization:
    p = new double(18.02);
    if (p != nullptr)
    {
        cout << "\n*p is " << *p << ".\n";
    }
    else
    {
        cout << "\nCouldn't get space for a single double!\a\n";
    }
    delete p;
    p = nullptr;  // clean up nice...

    // a few doubles from the heap:
    p = new double [40];
    if (p != nullptr)
    {
        *p = 18.03;
        p[1] = 18.04;
        p[39] = 18.05;
        cout << "\n First element:  " << p[0] << ".\n";
        cout << "Second element:  " << *(p+1) << ".\n";
        cout << "  Last element:  " << *(39+p) << ".\n";
        cout << "\nWhole thing:\n";
        print_per_line(p, 40);
    }
    else
    {
        cout << "\nCouldn't get space for an array of doubles!\a\n";
    }
    delete [] p;
    p = nullptr;  // clean up nice...

    // let's get interactive...
    cout << "\nHow many do you want?  ";
    cin >> max;
    max = max>=1?max:((cout<<"\nMoron!  You get 1!\a\n"),1);
    p = new double [max];
    if (p != nullptr)
    {
        for (short c = 0; c != max; c++)
        {
            p[c] = rand()%10001/10000.0+18.0;
        }
        cout << "\nYou have:\n";
        print_per_line(p, max);

        cout << "\nNow it is your turn to fill it.  Enter a letter "
                "to stop early...\n";
        count = read_to_fail(p,max);
        cout << "\nYour " << count << " numbers were:\n";
        print_per_line(p, count);
    }
    else
    {
        cout << "\nCouldn't get space for an array of doubles!\a\n";
    }
    delete [] p;
    p = nullptr;  // clean up nice...

    return 0;
}

void print_per_line(const double a[], long max, long wide)
{
    long per = 80/(wide+1);
    for (short c = 0; c != max; c++)
    {
        cout << setw(wide) << a[c] << ((c+1)%per==0?'\n':' ');
    }
    cout << endl;
    return;
}

long read_to_fail(double * a, long max)
{
    double * p = a;
    cin >> *p;
    while ((p-a+1) != max && !cin.fail())
    {
        cin >> *(++p);
    }
    return !cin.fail() ? p-a+1
                       : (cin.clear(),cin.ignore(numeric_limits<streamsize>::max(), '\n'),p-a);
}
