1

¿Cómo hago para dimensionar una matriz con los datos que carga el usuario en C++?

#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <vector>

using namespace std;

int main () {
    int a,b,fila=0,columna=0;
    system ("color F3");
    cout << "\t\t\t PROGRAMA DE MATRIZ EJ 1 C++" << endl << endl;
    cout << "Ingrese el valor de filas que quiere que tenga la matriz: "; cin >> fila;
    cout << "Ingrese el valor de columnas que quiere que tenga la matriz: "; cin >> columna;
    std::vector<int>Matriz(fila,columna);

    cout << "Ingrese el valor de los elementos de la matriz: " << endl;
    for(a = 0; a < fila ; a++)
    { 
        for (b = 0; b < columna ; a++)
            cin >> matriz[a][b];       
    }

    for(a = 0; a < fila ; a++)
    { 
        for (b = 0; b < columna ; b++)
            cout << matriz[a][b] << endl; 
    }
    system ("pause");
    return 0;
}

El error que tira es el siguiente

error: invalid types 'int[int]'
Alejandro Caro
  • 791
  • 11
  • 32

2 Answers2

3

Problema.

Completo desconocimiento de la librería estándar de plantillas (STL).

Solución.

Lee la documentación de la clase std::vector.

Descripción del problema, paso a paso.

La clase std::vector es un contenedor de la librería estándar de plantillas que permite almacenar datos de manera anexa en memoria y acceder a los elementos almacenados mediante el operador corchetes ([ y ]), podría considerarse como una versión ampliada y segura del arreglo tradicional.

Constructor.

El std::vector dispone de ocho constructores distintos de los que voy a mencionar sólo los tres más relevantes para esta pregunta:

  1. vector()

    Construye un vector vacío (delega en el constructor que recibe un allocator).

  2. vector( size_type count, const T& value, const Allocator& alloc = Allocator());

    Construye un vector con count elementos todos ellos inicializados al valor value, se usará el alojador alloc para alojar los datos.

  3. explicit vector( size_type count, const Allocator& alloc = Allocator() );

    Construye un vector con count elementos, todos los elementos serán alojados por el alojador alloc y serán inicializados con el valor por defecto del tipo alojado.

El constructor que has usado en tu caso:

std::vector<int>Matriz(fila,columna);

Es el segundo, así que al contrario de lo que (parece que) crees, no estás creando una Matriz de Y filas por X columnas si no un vector de fila elementos inicializados al valor columna

Operador corchetes.

El operador corchetes de std::vector (std::vector::operator []) dispone de dos sobrecargas, una de sólo lectura y otra de lectura-escritura:

  • reference operator[]( size_type pos );
  • const_reference operator[]( size_type pos ) const;

Devuelve en cada caso una referencia al dato almacenado (std::vector::reference o std::vector::const_reference), en tu caso:

cin >> matriz[a][b];

Suponiendo que matriz (con m minúscula) sea lo mismo1 que lo que Matriz (con M mayúscula) que has declarado unas líneas atrás, al usar el primer operador corchete [a] estás obteniendo una referencia al dato almacenado en matriz, que viendo la declaración sabemos que es int. Sobre el int obtenido entonces usas otro operador corchetes [b] y es ahí cuando obtienes el error que mencionas:

 error: invalid types 'int[int]'

Ya que intentas indexar con corchetes un tipo no indexable (int).

Propuesta.

Para conseguir lo que (parece que) quieres en el código que has mostrado, deberás usar un vector de vectores, para que sea más cómodo de usar te aconsejo definir un alias:

using Matriz = std::vector<std::vector<int>>;

Con ello, tu código podría quedar así:

int main () {
    std::size_t fila=0u,columna=0u;

    std::cout << "\t\t\t PROGRAMA DE MATRIZ EJ 1 C++\n\n";
    std::cout << "Ingrese el valor de filas que quiere que tenga la matriz: ";
    std::cin >> fila;

    std::cout << "Ingrese el valor de columnas que quiere que tenga la matriz: ";
    std::cin >> columna;

    using Matriz = std::vector<std::vector<int>>;
    // Utilizamos el segundo y tercer constructor de std::vector
    Matriz matriz = { fila, std::vector<int>(columna) };

    std::cout << "Ingrese el valor de los elementos de la matriz: \n";
    for(int a = 0; a < fila ; a++)
    { 
        for (int b = 0; b < columna ; a++)
            std::cin >> matriz[a][b];       
    }

    for(int a = 0; a < fila ; a++)
    { 
        for (int b = 0; b < columna ; b++)
            std::cout << matriz[a][b] << '\n'; 
    }

    return 0;
}

Date cuenta que he eliminado la línea using namespace std, consulta esta pregunta para saber por qué. También he eliminado los std::endl, consulta esta pregunta para saber por qué. También he cambiado el tipo de fila y columna a std::size_t ya que es el tipo que esperan los constructores de std::vector para las partes en que se usen tamaños y he eliminado las variables a y b que pueden (y deben) crearse en los bucles en que son usadas (no antes), respecto a los bucles, una posible mejora sería usar los bucles de rango (ya que trabajamos con contenedores):

    std::cout << "Ingrese el valor de los elementos de la matriz: \n";
    for(auto &fila : matriz)
    { 
        for (auto &valor : fila)
            std::cin >> valor;
    }

    for(auto &fila : matriz)
    { 
        for (auto &valor : fila)
            std::cout << valor << '\n'; 
    }

1Sorpresa: No lo es. En C++ los nombres de identificadores son sensibles a mayúsculas/minúsculas.

PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
1

En el caso que expones, no hace falta siquiera que trabajes con matrices de verdad.

Para usar un ::std::vector< int >, basta con que, al indicar su tamaño, calcules filas * columnas:

#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <vector>

using namespace std;

int main () {
  int a,fila,columna;
  system ("color F3");
  cout << "\t\t\t PROGRAMA DE MATRIZ EJ 1 C++" << endl << endl;
  cout << "Ingrese el valor de filas que quiere que tenga la matriz: "; cin >> fila;
  cout << "Ingrese el valor de columnas que quiere que tenga la matriz: "; cin >> columna;
  vector<int> Matriz(fila*columna);

  cout << "Ingrese el valor de los elementos de la matriz: " << endl;

  for(a = 0; a < fila*columna ; a++)
    cin >> Matriz[a];      

  cout << "Matriz introducida:\n";

  for(a = 0; a < fila*columna ; a++ )
    cout << Matriz[a] << endl; 

  system ("pause");
  return 0;
}

Como verás, he eliminado la variable b, que ya no hace falta. Y he dejado sin inicializar filas y columnas, ya que de todos modos los vamos a pedir al usuario.

Podíamos haber usado la b para almacenar el resultado de filas * columnas, y no tener que estar repitiéndolo en cada bucle; una simple modificación que puedes hacerle.

Trauma
  • 25,297
  • 4
  • 37
  • 60
  • 1
    Que pasa si forzosamente necesita un arreglo de 2 dimensiones, ejemplo si el solamente quiere consultar los datos de la segundo fila, seria bueno que explicaras como puede simular este mecanismo en una matriz de una sola dimension. – JGarnica Jun 10 '17 at 17:09