Ahora ya funciona pero si te has dado cuenta, pides los datos dos veces seguidas. Una vez en el <main> y otra vez en la función <matrizCuadrada()>...
Te comento las diferencias entre el filtro <do while> y el <while> ya que esto se puede hacer de ambas formas.
Un bloque de código dentro de un <do while> siempre se ejecuta al menos una vez aunque la condición sea falsa ya que primero está el <do> y luego el <while>. Es como "primero haces y luego compruebas". En cambio un <while> es justo lo contrario; "primero compruebas y luego ya si eso, haces".
Aquí te muestro un bloque infinito. ¿Por qué si la condición de primeras no se cumple? Pues porque primero mostramos el 0, luego lo incrementamos <iteracion = 1> y luego comprobamos si es mayor que 0. Y como sí que lo es pues ya se ejecuta de forma infinita.
int iteracion = 0;
do{
cout << iteracion << endl;
iteracion++;
} while(iteracion > 0);
Lo mismo con un <while>. La parte interna del bucle nunca se ejecuta. Al principio iteracion vale 0, comprobamos si es mayor que 0 y como no lo es, se acabó.
int iteracion = 0;
while(iteracion > 0){
cout << iteracion << endl;
iteracion++;
}
Entonces ahora te muestro las opciones que tienes:
- Alternativa 1: Pedir los datos únicamente dentro de <matrizCuadrada()>. Entonces sería con un <do while>.
void matrizCuadrada(int m[][TAM], int &nFil, int &nCol){
do{
pedirDatos(nFil, nCol);
} while(nFil != nCol);
// el resto de la funcion
}
- Alternativa 2: Pedir los datos en el <main> y dentro de la función <matrizCuadrada()> comprobarlos para que si no son iguales los pida de nuevo.
void matrizCuadrada(int m[][TAM], int &nFil, int &nCol){
while(nFil != nCol)
pedirDatos(nFil, nCol);
// el resto de la funcion
}
- Alternativa 3: La más correcta creo yo. Para no tener que ir pasando siempre las dimensiones por referencia, que podrías acabar modificándolas sin querer; haz el filtro dentro de <pedirDatos()> y así te aseguras que cuando acaba esa función la matriz ya es cuadrada.
void pedirDatos(int &nFil, int &nCol){
do{
cout << "Introduce las dimensiones de la matriz (NxN): ";
cin >> nFil >> nCol;
} while(nFil != nCol);
}
Con esta última opción ya no tienes que usar siempre el paso por referencia y así evitar errores mayores.
Es más, yo dejaría el esquema general del programa en algo así
:
void pedirDatos(int&, int&);
void generarMatriz(int [][TAM], const int, const int);
void mostrarMatriz(const int [][TAM], const int, const int);
bool esSimetrica(const int [][TAM], const int, const int);
En el caso de <esSimetrica()>. Cuando se usa una función para comprobar algo es mejor que devuelva <true/false> y luego tú ya verás lo que haces con ello. Imagina un programa muy grande donde tienes que comprobar si 100 matrices son simétricas y vas mostrando por pantalla el resultado de cada una, cuando no es necesario.
Entonces es mejor hacer que devuelva un <bool> de si es simétrica o no y ya en el <main> haces lo que quieras. Algo así:
bool esSimetrica(const int matriz[][TAM], const int nFil, const int nCol){
bool simetrica = true;
for(size_t i = 0; i < nFil && simetrica; i++)
for(size_t j = 0; j < nCol && simetrica; j++)
simetrica = matriz[i][j] == matriz[j][i];
return simetrica;
}
int main(){
// todo el programa
if(esSimetrica(matriz, nFil, nCol))
cout << "La matriz es simetrica" << endl;
else
cout << "La matriz no es simetrica" << endl;
}