0

As part of a larger assignment I am working on, I am trying to find a way to find rows and columns of a two dimensional array from input alone.

Currently what I am doing to set parameters is just asking for rows and columns. (see below/disregard some of the directives, initializes).

But what I'd like to do like be able to do is just skip the part where I am setting rows and columns by way of input; and instead be able to just input the values of the array in a sort of matrix way and obtain rows and columns that way. Is this possible?

//what I'd to be able to do
Enter values:
1 2 3 4
5 6 7 8
//the array would then be ex_array[2][4]

//current method I am using
#include<iostream>
#include<cmath>
#include <iomanip> 
using namespace std;

int main()
{
   int n,m;
   double sqt;
   double elevation;
   double answer;
   int array[10][10];
   int lowest,highest;
   int lowest_x_coordinate_index;
   int lowest_y_coordinate_index;
   int highest_x_coordinate_index;
   int highest_y_coordinate_index;

   cout<<"Enter No of rows: ";
   cin>>m;

   cout<<"Enter No of columns: ";
   cin>>n;

   cout<<"Enter values:\n";
   //Read array values from keyboard
   for(int i=0;i<m;i++)
   {
       for(int j=0;j<n;j++)
       {
           cin>>array[i][j];
       }
   }
}
Sam
  • 31
  • 1
  • 6
  • You could read a line and count the columns. The rows is more tricky, because you don't know when to stop looking for input. But if you enter an empty line when you are ready entering rows, it is possible. Read a string using [std::getline()](http://www.cplusplus.com/reference/string/string/getline/), and parse the integers from the string. – wimh May 17 '15 at 21:34

2 Answers2

0

No, unless you pass the array by reference, since otherwise the array decays to a pointer to its first element. Example of passing by reference:

#include <iostream>

template <typename T, size_t M, size_t N>
void f(T (&arr)[M][N])
{
    std::cout << "Size: " << M << " " << N;
}

int main()
{
    int arr[2][3];
    f(arr); // can deduce the size here
}

If you ask whether you can create an array with a variable length, the answer is still no, C++ does not allow variable-sized arrays. Your only choice is to use dynamic allocation,

int M = 10, N = 20; // sizes, can be read also from input
int* array = new int*[M];
for(size_t i = 0 ; i < N; ++i)
    array[i] = new int[N];

then don't forget to delete it when you're done with it

for(size_t i = 0 ; i < N; ++i)
    delete[] array[i];
delete[] array;

As you can see, things start to look not so nice. Instead of using plain C-style arrays, try to use the standard library std::vector (or std::array for compile time fixed-size array). They are much more flexible and less error prone. Example:

std::vector<std::vector<int>> v(M, std::vector<int>(N)); // vector of vector, M x N
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • This seems to completely miss the OP's actual question, which is about discerning user input. – Steve Fallows May 17 '15 at 21:54
  • @SteveFallows I just edited, as I realized that OP may have wanted something else. The question is a bit unclear though: *I am trying to find a way to find rows and columns of a two dimensional array from input alone*? – vsoftco May 17 '15 at 21:55
0

Yes (if I have correctly understood your question).

This can be done :

Enter values:
1 2 3 4
5 6 7 8
                         <- empty line
//the array would then be ex_array[2][4]

You will have to use :

  • getline to read input line by line
  • stringstream to parse each individual line
  • a vector to build each line
  • a vector of arrays to build the full array

But ... there is no convenient way in C++ to declare a 2D array with runtime known size ! (ref : How do I declare a 2d array in C++ using new?), and you end with at best an array of arrays. But if you accept to declare the array with a static size like it is in your code it is much simpler :

#include <string>
#include <iostream>
#include <sstream>
#include <vector>

int main() {
    std::string line;
    int cols = -1;
    int linenum = 0;
    int arr[10][10];

    for(;;) {
        linenum++;
        int i;
        std::getline(std::cin, line);
        if (line == std::string("")) break;
        if (linenum >= 10) {
            std::cerr << "Too much lines (limited to 10)" << std::endl;
            return 1;
        }
        std::istringstream ss(line);
        std::vector<int> values;
        for(;;) {
            ss >> i;
            if (ss.fail()) break;
            values.push_back(i);
        }
        if (! ss.eof()) {
            std::cerr << "Incorrect input line " << linenum << std::endl;
            return 1;
        }
        if (cols == -1) {
            cols = values.size();
            if (cols > 10) {
                std::cerr << "Too much columns " << cols << ">10" << std::endl;
                return 1;
            }
        }
        else if (cols != values.size()) {
            std::cerr << "Error line " << linenum << " : " << cols;
            std::cerr << " columns expected - found " << values.size();
            std::cerr << std::endl;
            return 1;
        }
        for(int i=0; i<cols; i++) arr[linenum - 1][i] = values[i];
    }
    int nrows = linenum -1;
    std::cout << nrows << " lines - " << cols << " columns" << std::endl;
    for (int i=0; i<nrows; i++) {
        for (int j=0; j<cols; j++) {
            std::cout << " " << arr[i][j];
        }
        std::cout << std::endl;
    }
    return 0;
}

With input of :

1 2 3 4
5 6 7 8

it gives :

2 lines - 4 columns
 1 2 3 4
 5 6 7 8
Community
  • 1
  • 1
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252